=====BeautifulSoup===== eautifulSoup является библиотекой Python для парсинга HTML и XML документов. Часто используется для скрапинга веб-страниц. BeautifulSoup позволяет трансформировать сложный HTML-документ в сложное древо различных объектов Python. Это могут быть теги, навигация или комментарии. [[https://tedboy.github.io/bs4_doc/generated/generated/bs4.BeautifulSoup.html|Описание всех методов]] ====Установка BeautifulSoup в Python==== Для установки необходимых модулей используется команда pip3. Для начала требуется установить lxml модуль, который используется в BeautifulSoup. $ sudo pip3 install lxml BeautifulSoup устанавливается при помощи использования указанной ниже команды. $ sudo pip3 install bs4 ====Пример HTML-кода страницы==== В последующих примерах будет использован данный HTML-файл: Header

Operating systems

FreeBSD is an advanced computer operating system used to power modern servers, desktops, and embedded platforms.

Debian is a Unix-like computer operating system that is composed entirely of free software.

====BeautifulSoup простой пример парсинга HTML==== В первом примере будет использован BeautifulSoup модуль для получения трех тегов. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') print(soup.h2) print(soup.head) print(soup.li) Код в данном примере позволяет вывести HTML-код трех тегов. from bs4 import BeautifulSoup Здесь производится импорт класса BeautifulSoup из модуля bs4. Таким образом, BeautifulSoup является главным рабочим классом. with open("index.html", "r") as f: contents = f.read() Открывается файл index.html и производится чтение его содержимого при помощи метода read(). soup = BeautifulSoup(contents, 'lxml') Создается объект BeautifulSoup. Данные передаются конструктору. Вторая опция уточняет объект парсинга. print(soup.h2) print(soup.head) Далее выводится HTML-код следующих двух тегов: h2 и head. print(soup.li) В примере много раз используются элементы li, однако выводится только первый из них. $ ./simple.py

Operating systems

Header
  • Solaris
  • Это результат вывода. ====BeautifulSoup теги, атрибуты name и text==== Атрибут name указывает на название тега, а атрибут text указывает на его содержимое. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') print("HTML: {0}, name: {1}, text: {2}".format(soup.h2, soup.h2.name, soup.h2.text)) Код в примере позволяет вывести HTML-код, название и текст h2 тега. $ ./tags_names.py HTML:

    Operating systems

    , name: h2, text: Operating systems
    Это результат вывода. ====BeautifulSoap перебираем HTML теги==== Метод //recursiveChildGenerator()// позволяет перебрать содержимое HTML-документа. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') for child in soup.recursiveChildGenerator(): if child.name: print(child.name) Данный пример позволяет перебрать содержимое HTML-документа и вывести названия всех его тегов. $ ./traverse_tree.py html head title meta body h2 ul li li li li li p p Данные теги являются частью рассматриваемого HTML-документа. ====BeautifulSoup атрибут children==== При помощи атрибута children можно вывести все дочерние теги. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') root = soup.html root_childs = [e.name for e in root.children if e.name is not None] print(root_childs) В данном примере извлекаются дочерние элементы html тега, после чего они помещаются в список Python и выводятся в консоль. Так как атрибут children также убирает пробелы между тегами, необходимо добавить условие, которое позволяет выбирать только названия тегов. $ ./get_children.py ['head', 'body'] Следовательно, у тегов html есть два дочерних элемента: head и body. ====BeautifulSoup атрибут descendants==== При помощи атрибута descendants можно получить список всех потомков (дочерних элементов всех уровней) рассматриваемого тега. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') root = soup.body root_childs = [e.name for e in root.descendants if e.name is not None] print(root_childs) Данный пример позволяет найти всех потомков главного тега body. $ ./get_descendants.py ['h2', 'ul', 'li', 'li', 'li', 'li', 'li', 'p', 'p'] Перечисленные выше теги являются потомками главного тега body. ====BeautifulSoup и веб-скрапинг HTML==== Requests является простой HTTP библиотекой в Python. Она позволяет использовать разнообразные методы для получения доступа к веб-ресурсам при помощи HTTP. from bs4 import BeautifulSoup import requests as req resp = req.get("http://www.something.com") soup = BeautifulSoup(resp.text, 'lxml') print(soup.title) print(soup.title.text) print(soup.title.parent) Данный пример извлекает название рассматриваемой веб-страницы. Здесь также выводится имя ее родителя. resp = req.get("http://www.something.com") soup = BeautifulSoup(resp.text, 'lxml') Здесь мы получаем информацию о веб-странице. print(soup.title) print(soup.title.text) print(soup.title.parent) Код выше помогает вывести HTML-код заголовка, его текст, а также HTML-код его родителя. $ ./scraping.py Something. Something. Something. Это результат вывода. ====BeautifulSoup метод prettify()==== При помощи метода prettify() можно добиться того, чтобы HTML-код выглядел аккуратнее. from bs4 import BeautifulSoup import requests as req resp = req.get("http://www.something.com") soup = BeautifulSoup(resp.text, 'lxml') print(soup.prettify()) Таким образом, мы оптимизируем HTML-код простой веб-страницы. 3 4 5 6 7 8 9 10 11 $ ./prettify.py Something. Something. Это результат вывода. ====BeautifulSoup метод find(), поиск элементов по id==== При помощи метода find() можно найти элементы страницы, используя различные опорные параметры, id в том числе. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') #print(soup.find("ul", attrs={ "id" : "mylist"})) print(soup.find("ul", id="mylist")) Код в примере находит тег ul, у которого id mylist. Строка в комментарии является альтернативным способом выполнить то же самое задание. ====BeautifulSoup метод find_all() поиск всех тегов в HTML==== При помощи метода find_all() можно найти все элементы, которые соответствуют заданным критериям. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') for tag in soup.find_all("li"): print("{0}: {1}".format(tag.name, tag.text)) Код в примере позволяет найти и вывести на экран все li теги. $ ./find_all.py li: Solaris li: FreeBSD li: Debian li: NetBSD Это результат вывода. Метод //find_all()// также при поиске использует список из названий тегов. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') tags = soup.find_all(['h2', 'p']) for tag in tags: print(" ".join(tag.text.split())) В данном примере показано, как найти все h2 и p элементы, после чего вывести их содержимое на экран. Метод //find_all()// также может использовать функцию, которая определяет, какие элементы должны быть выведены. from bs4 import BeautifulSoup def myfun(tag): return tag.is_empty_element with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') tags = soup.find_all(myfun) print(tags) Данный пример выводит пустые элементы. $ ./find_by_fun.py [] Единственным пустым элементом в документе является meta. Также можно найти запрашиваемые элементы, используя регулярные выражения. import re from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') strings = soup.find_all(string=re.compile('BSD')) for txt in strings: print(" ".join(txt.split())) В данном примере выводится содержимое элементов, в которых есть строка с символами ‘BSD’. $ ./regex.py FreeBSD NetBSD FreeBSD is an advanced computer operating system used to power modern servers, desktops, and embedded platforms. Это результат вывода. ====BeautifulSoup методы select() и select_one() CSS селекторы==== При помощи методов //select()// и //select_one()// для нахождения запрашиваемых элементов можно использовать некоторые CSS селекторы. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') print(soup.select("li:nth-of-type(3)")) В данном примере используется CSS селектор, который выводит на экран HTML-код третьего по счету элемента li. $ ./select_nth_tag.py
  • Debian
  • Данный элемент li является третьим в списке. В CSS символ # используется для выбора тегов по их id-атрибутам. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') print(soup.select_one("#mylist")) В данном примере выводятся элементы, которых есть id под названием mylist. ====find_parent и find_parents==== Возвращает ближайшего родителя этого тега, который соответствует заданным критериям. BeautifulSoup.find_parent(name=None, attrs={}, **kwargs) Возвращает родителей этого тега, которые соответствуют заданным критериям. BeautifulSoup.findParents(name=None, attrs={}, limit=None, **kwargs) ====find_next_sibling и find_previous_sibling==== Возвращает ближайшего родственника к этому тегу, который соответствует заданным критериям и появляется после этого тега в документе. BeautifulSoup.find_next_sibling(name=None, attrs={}, text=None, **kwargs) Возвращает ближайшего родственника к этому тегу, который соответствует заданным критериям и отображается перед этим тегом в документе. BeautifulSoup.find_previous_sibling(name=None, attrs={}, text=None, **kwargs) ====BeautifulSoup метод append() добавление нового HTML-тега==== Метод //append()// добавляет в рассматриваемый HTML-документ новый тег. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') newtag = soup.new_tag('li') newtag.string='OpenBSD' ultag = soup.ul ultag.append(newtag) print(ultag.prettify()) В примере выше показано, как в HTML-документ добавить новый тег li. newtag = soup.new_tag('li') newtag.string='OpenBSD' Для начала, требуется создать новый тег при помощи метода //new_tag()//. ultag = soup.ul Далее создается сноска на тег ul. ultag.append(newtag) Затем созданный ранее тег li добавляется к тегу //ul//. print(ultag.prettify()) Таким образом, тег ul выводится аккуратно отформатированным. ====BeautifulSoup метод insert() вставка HTML-тега==== Метод insert() позволяет вставить тег в определенно выбранное место. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') newtag = soup.new_tag('li') newtag.string='OpenBSD' ultag = soup.ul ultag.insert(2, newtag) print(ultag.prettify()) В примере показано, как поставить тег //li// на третью позицию в выбранном //ul// теге. ====BeautifulSoup метод replace_with() замена текста в теге==== Метод //replace_with()// заменяет содержимое выбранного элемента. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') tag = soup.find(text="Windows") tag.replace_with("OpenBSD") print(soup.ul.prettify()) В примере показано, как при помощи метода find() найти определенный элемент, а затем, используя метод replace_with(), заменить его содержимое. ====BeautifulSoup метод decompose() удаление HTML-тега=== Метод //decompose()// удаляет определенный тег из структуры документа и уничтожает его. from bs4 import BeautifulSoup with open("index.html", "r") as f: contents = f.read() soup = BeautifulSoup(contents, 'lxml') ptag2 = soup.select_one("p:nth-of-type(2)") ptag2.decompose() print(soup.body.prettify()) В данном примере показано, как удалить второй элемент p в документе. В данном руководстве было показано, как использовать библиотеку BeautifulSoup в Python. ====Регулярные выражения==== Страничка для парсинга: Document
    Petr
    Python developer
    salary: 2700 usd per month

    some@mail

    Alena
    Copywriter
    salary: 2100 usd

    @twitter

    some@mail

    Kate
    Copywriter
    2100 usd

    @twitter

    some@mail

    Ksenia
    Designer
    2300 usd
    Links:

    Мой твиттер @twitter Подписывайтесь

    Это не мое мыло
    from bs4 import BeautifulSoup import re def get_salary(s): print(s) # salary: 2700 usd per month pattern = r'\d{1,9}' salary = re.findall(pattern, s)[0] print(salary) def main(): file = open('index.html').read() soup = BeautifulSoup(file, 'lxml') salary = soup.find_all('div', {'data-set': 'salary'}) for i in salary: get_salary(i.text) результат salary: 2700 usd per month 2700 salary: 2100 usd 2100 2100 usd 2100 2300 usd 2300 from bs4 import BeautifulSoup import re file = open('index.html').read() soup = BeautifulSoup(file, 'lxml') salary = soup.find_all('div', text=re.compile('\d{1,9}')) for i in salary: print(i.text) результат salary: 2700 usd per month salary: 2100 usd 2100 usd 2300 usd