How can BeautifulSoup be used to extract ‘href’ links from a website?
BeautifulSoup is a third party Python library that is used to parse data from web pages. It helps in web scraping, which is a process of extracting, using, and manipulating the data from different resources.
Web scraping can also be used to extract data for research purposes, understand/compare market trends, perform SEO monitoring, and so on.
The below line can be run to install BeautifulSoup on Windows −
Following is an example −
Example
Output
Explanation
The required packages are imported, and aliased.
The website is defined.
The url is opened, and data is read from it.
The ‘BeautifulSoup’ function is used to extract text from the webpage.
The ‘find_all’ function is used to extract text from the webpage data.
Руководство по синтаксическому анализу HTML с помощью BeautifulSoup в Python
Веб-скрапинг — это программный сбор информации с различных веб-сайтов. Несмотря на то, что существует множество библиотек и фреймворков на разных языках, которые могут извлекать веб-данные, Python уже давно стал популярным выбором из-за множества опций для парсинга веб-страниц.
Эта статья даст вам ускоренный курс по парсингу веб-страниц в Python с помощью Beautiful Soup — популярной библиотеки Python для синтаксического анализа HTML и XML.
Этический веб-скрапинг
Веб-скрапинг повсеместен и дает нам данные, как если бы мы получали их с помощью API. Однако, как хорошие граждане Интернета, мы обязаны уважать владельцев сайтов. Вот несколько принципов, которых должен придерживаться веб-парсер:
- Не заявляйте, что извлеченный контент принадлежит вам. Владельцы веб-сайтов иногда тратят много времени на создание статей, сбор сведений о продуктах или сбор другого контента. Мы должны уважать их труд и оригинальность.
- Не парсите веб-сайт, который не хочет этого. Веб-сайты иногда поставляются с файлом robots.txt , который определяет части веб-сайта, которые можно получить. У многих веб-сайтов также есть Условия использования, которые могут не разрешать парсинг. Мы должны уважать веб-сайты, которые не хотят что-бы их контент парсили.
- Есть ли уже доступный API? Прекрасно, нам не нужно писать парсер. API-интерфейсы создаются для предоставления доступа к данным контролируемым способом, определенным владельцами данных. Мы предпочитаем использовать API, если они доступны.
- Отправка запросов на веб-сайт может отрицательно сказаться на его работе. Веб-парсер, который делает слишком много запросов, может быть таким же изнурительным, как и DDOS-атака. Мы должны выполнять чистку ответственно, чтобы не нарушать нормальную работу веб-сайта.
Обзор Beautiful Soup
HTML-содержимое веб-страниц можно проанализировать и очистить с помощью Beautiful Soup. В следующем разделе мы рассмотрим те функции, которые полезны для очистки веб-страниц.
Что делает Beautiful Soup таким полезным, так это множество функций, которые он предоставляет для извлечения данных из HTML. На этом изображении ниже показаны некоторые функции, которые мы можем использовать:
Давайте поработаем и посмотрим, как мы можем анализировать HTML с помощью Beautiful Soup. Рассмотрим следующую HTML-страницу, сохраненную в файл как doc.html :
Следующие фрагменты кода протестированы на Ubuntu 20.04.1 LTS . Вы можете установить модуль BeautifulSoup , набрав в терминале следующую команду:
HTML-файл doc.html необходимо подготовить. Это делается путем передачи файла конструктору BeautifulSoup , давайте воспользуемся для этого интерактивной оболочкой Python, чтобы мы могли мгновенно распечатать содержимое определенной части страницы:
Теперь мы можем использовать Beautiful Soup для навигации по нашему веб-сайту и извлечения данных.
Переход к определенным тегам
Из объекта soup, созданного в предыдущем разделе, получим тег заголовка doc.html :
Вот разбивка каждого компонента, который мы использовали для получения названия:
Beautiful Soup — мощный инструмент, потому что наши объекты Python соответствуют вложенной структуре HTML-документа, который мы очищаем.
Чтобы получить текст первого тега <a> , введите следующее:
Чтобы получить заголовок в HTML теге body (обозначается классом «title»), введите в терминале следующее:
Для глубоко вложенных HTML-документов навигация может быстро стать утомительной. К счастью, Beautiful Soup поставляется с функцией поиска, поэтому нам не нужно перемещаться, чтобы получить элементы HTML.
Поиск тегов
Метод find_all() принимает HTML-тег в качестве строкового аргумента и возвращает список элементов, которые соответствуют указанной поисковой строке. Например, если мы хотим, найти все теги a в doc.html :
Мы увидим этот список тегов a в качестве вывода:
Вот разбивка каждого компонента, который мы использовали для поиска тега:
Мы также можем искать теги определенного класса, указав аргумент class_ . Beautiful Soup использует class_ , потому что class является зарезервированным ключевым словом в Python. Поищем все теги a , у которых есть класс element:
Поскольку у нас есть только две ссылки с классом «element», вы увидите следующий результат:
Что, если бы мы хотели получить ссылки, встроенные в теги a ? Давайте получим атрибут ссылки href с помощью опции find() . Он работает точно так же как find_all() , но возвращает первый соответствующий элемент вместо списка. Введите это в свою оболочку:
Функции find() и find_all() также принимают регулярное выражение вместо строки. За кулисами текст будет фильтроваться с использованием метода скомпилированного регулярного выражения search() . Например:
Список после итерации выбирает теги, начинающиеся с символа b , который включает <body> и <b> :
Мы рассмотрели наиболее популярные способы получения тегов и их атрибутов. Иногда, особенно для менее динамичных веб-страниц, нам просто нужен текст. Посмотрим, как мы сможем это получить!
Получение всего текста
Функция get_text() извлекает весь текст из HTML — документа. Получим весь текст HTML-документа:
Ваш результат должен быть таким:
Иногда печатаются символы новой строки, поэтому ваш вывод также может выглядеть так:
Теперь, когда мы понимаем, как использовать Beautiful Soup, давайте очистим веб-сайт!
Beautiful Soup в действии — очистка списка книг
Теперь, когда мы освоили компоненты Beautiful Soup, пришло время применить наши знания на практике. Давайте создадим парсер для извлечения данных с https://books.toscrape.com/ и сохранения их в файл CSV. Сайт содержит случайные данные о книгах и является отличным местом для проверки ваших методов парсинга.
Сначала создайте новый файл с именем scraper.py . Импортируем все библиотеки, которые нам нужны для этого скрипта:
В упомянутых выше модулях:
- requests — выполняет URL-запрос и получает HTML-код сайта
- time — ограничивает, сколько раз мы очищаем страницу одновременно
- csv — помогает нам экспортировать очищенные данные в файл CSV
- re — позволяет нам писать регулярные выражения, которые пригодятся для выбора текста на основе его шаблона
- bs4 — модуль парсинга для парсинга HTML
Вы уже установили bs4 , а time , csv и re являются встроенными пакетами в Python. Вам нужно будет установить только модуль requests следующим образом:
Прежде чем начать, вам нужно понять, как структурирован HTML-код веб-страницы. В вашем браузере перейдите по адресу http://books.toscrape.com/catalogue/page-1.html. Затем щелкните правой кнопкой мыши компоненты веб-страницы, которые нужно очистить, и нажмите кнопку проверки, чтобы понять иерархию тегов, как показано ниже.
Это покажет вам базовый HTML-код того, что вы проверяете. На следующем рисунке показаны эти шаги:
Изучив HTML, мы узнаем, как получить доступ к URL-адресу книги, изображению обложки, заголовку, рейтингу, цене и другим полям из HTML. Давайте напишем функцию, которая очищает элемент книги и извлекает его данные:
Последняя строка приведенного выше фрагмента указывает на функцию для записи списка очищенных строк в файл CSV. Давайте добавим эту функцию сейчас:
Поскольку у нас есть функция, которая может очищать страницу и экспортировать в CSV, нам нужна другая функция, которая просматривает веб-сайт с разбивкой на страницы, собирая данные о книгах на каждой странице.
Для этого давайте посмотрим на URL-адрес, для которого мы пишем этот парсер:
Единственным изменяющимся элементом URL-адреса является номер страницы. Мы можем динамически форматировать URL-адрес, чтобы он стал исходным URL-адресом:
Этот строковый URL-адрес с номером страницы можно получить с помощью метода requests.get() . Затем мы можем создать новый объект BeautifulSoup. Каждый раз, когда мы получаем объект soup, проверяется наличие кнопки «next», чтобы мы могли остановиться на последней странице. Мы отслеживаем счетчик номера страницы, который увеличивается на 1 после успешного извлечения страницы.
Функция browse_and_scrape() , вызывается рекурсивно, пока функция soup.find(«li»,class_=»next») не вернет None . На этом этапе код очистит оставшуюся часть веб-страницы и завершит работу.
Для последней части пазла мы запускаем процесс парсинга. Мы определяем seed_url и вызываем browse_and_scrape() для получения данных. Это делается в блоке if __name__ == «__main__» :
Вы можете выполнить сценарий, как показано ниже, в вашем терминале и получить вывод как:
Очищенные данные можно найти в текущем рабочем каталоге под именем файла allBooks.csv . Вот пример содержимого файла:
Вывод
В этом уроке мы узнали об этике написания хороших парсеров. Затем мы использовали Beautiful Soup для извлечения данных из HTML-файла с помощью свойств объекта Beautiful Soup и его различных методов, таких как find() , find_all() и get_text() . Затем мы создали парсер, который извлекает список книг в Интернете и экспортирует его в CSV.
Очистка веб-страниц — полезный навык, который помогает в различных действиях, таких как извлечение данных, таких как API, выполнение контроля качества на веб-сайте, проверка неработающих URL-адресов на веб-сайте и многое другое.
Как получить ссылку из тега python
Время прочтения: 4 мин.
Одна из задач, которая стояла в рамках проекта, нацеленного на исследование мер поисковой оптимизации (SEO, search engine optimization) информационных ресурсов дочерних структур организации, предполагала поиск всех ссылок и выявление среди них так называемых «мертвых (битых) ссылок», отсылающих на несуществующий сайт, страницу, файл, что в свою очередь понижает рейтинг информационного ресурса.
В этом посте я хочу поделиться одним из способов извлечения всех ссылок сайта (внутренних и внешних), который поможет при решении подобных задач.
Посмотрим, как можно создать инструмент извлечения ссылок в Python, используя пакет requests и библиотеку BeautifulSoup. Итак,
Импортируем необходимые модули:
Затем определим две переменные: одну для всех внутренних ссылок (это URL, которые ссылаются на другие страницы того же сайта), другую для внешних ссылок вэб-сайта (это ссылки на другие сайты).
Далее создадим функцию для проверки URL – адресов. Это обеспечит правильную схему в ссылке — протокол, например, http или https и имя домена в URL.
На следующем шаге создадим функцию, возвращающую все действительные URL-адреса одной конкретной веб-страницы:
Теперь получим все HTML теги, содержащие все ссылки вэб-страницы.
В итоге получаем атрибут href и проверяем его. Так как не все ссылки абсолютные, возникает необходимость выполнить соединение относительных URL-адресов и имени домена. К примеру, когда найден href — «/search» и URL — «google.com» , то в результате получим «google.com/search».
В следующем шаге удаляем параметры HTTP GET из URL-адресов:
Если URL-адрес недействителен/URL уже находится в int_url , следует перейти к следующей ссылке.
Если URL является внешней ссылкой, вывести его и добавить в глобальный набор ext_url и перейдти к следующей ссылке.
И наконец, после всех проверок получаем URL, являющийся внутренней ссылкой; выводим ее и добавляем в наборы urls и int_url
Напоминаю, что эта функция захватывает ссылки одной вэб-страницы.
Теперь создадим функцию, которая сканирует весь веб-сайт. Данная функция получает все ссылки на первой странице сайта, затем рекурсивно вызывается для перехода по всем извлеченным ссылкам. Параметр max_urls позволяет избежать зависания программы на больших сайтах при достижении определенного количества проверенных URL-адресов.
Итак, проверим на сайте, к которому имеется разрешение, как все это работает:
Вот фрагмент результата работы программы:
Обратите внимание, что многократный запрос к одному и тому же сайту за короткий промежуток времени может привести к тому, что ваш IP-адрес будет заблокирован. Ссылка на оригинал поста.
Модуль BeautifulSoup4 в Python, разбор HTML.
BeautifulSoup4 (bs4) — это библиотека Python для извлечения данных из файлов HTML и XML. Для естественной навигации, поиска и изменения дерева HTML, модуль BeautifulSoup4, по умолчанию использует встроенный в Python парсер html.parser . BS4 так же поддерживает ряд сторонних парсеров Python, таких как lxml , html5lib и xml (для разбора XML-документов).
Установка BeautifulSoup4 в виртуальное окружение:
Содержание:
Выбор парсера для использования в BeautifulSoup4.
BeautifulSoup4 представляет один интерфейс для разных парсеров, но парсеры неодинаковы. Разные парсеры, анализируя один и того же документ создадут различные деревья HTML. Самые большие различия будут между парсерами HTML и XML. Так же парсеры различаются скоростью разбора HTML документа.
Если дать BeautifulSoup4 идеально оформленный документ HTML, то различий построенного HTML-дерева не будет. Один парсер будет быстрее другого, но все они будут давать структуру, которая выглядит точно так же, как оригинальный документ HTML. Но если документ оформлен с ошибками, то различные парсеры дадут разные результаты.
Различия в построении HTML-дерева разными парсерами, разберем на короткой HTML-разметке: <a></p> .
Парсер lxml .
- Для запуска примера, необходимо установить модуль lxml .
- Очень быстрый, имеет внешнюю зависимость от языка C.
- Нестрогий.
Обратите внимание, что тег <a> заключен в теги <body> и <html> , а висячий тег </p> просто игнорируется.
Парсер html5lib .
- Для запуска примера, необходимо установить модуль html5lib .
- Ну очень медленный.
- Разбирает страницы так же, как это делает браузер, создавая валидный HTML5.
Обратите внимание, что парсер html5lib НЕ игнорирует висячий тег </p> , и к тому же добавляет открывающий тег <p> . Также html5lib добавляет пустой тег <head> ( lxml этого не сделал).
Встроенный в Python парсер html.parser .
- Не требует дополнительной установки.
- Приличная скорость, но не такой быстрый, как lxml .
- Более строгий, чем html5lib .
Как и lxml , встроенный в Python парсер игнорирует закрывающий тег </p> . В отличие от html5lib , этот парсер не делает попытки создать правильно оформленный HTML-документ, добавив теги <html> или <body> .
Вывод: Парсер html5lib использует способы, которые являются частью стандарта HTML5, поэтому он может претендовать на то, что его подход самый "правильный".
Основные приемы работы с BeautifulSoup4.
Чтобы разобрать HTML-документ, необходимо передать его в конструктор класса BeautifulSoup() . Можно передать строку или открытый дескриптор файла:
Первым делом документ конвертируется в Unicode, а HTML-мнемоники конвертируются в символы Unicode:
Дальнейшие примеры будут разбираться на следующей HTML-разметке.
Передача этого HTML-документа в конструктор класса BeautifulSoup() создает объект, который представляет документ в виде вложенной структуры:
Навигация по структуре HTML-документа:
Перемещаться по одному уровню можно при помощи атрибутов .previous_sibling и .next_sibling . Например, в представленном выше HTML, теги <a> обернуты в тег <p> — следовательно они находятся на одном уровне.
Так же можно перебрать одноуровневые элементы данного тега с помощью .next_siblings или .previous_siblings .
Атрибут .next_element строки или HTML-тега указывает на то, что было разобрано непосредственно после него. Это могло бы быть тем же, что и .next_sibling , но обычно результат резко отличается.
Возьмем последний тег <a> , его .next_sibling является строкой: конец предложения, которое было прервано началом тега <a> :
Однако .next_element этого тега <a> — это то, что было разобрано сразу после тега <a> — это слово Tillie, а не остальная часть предложения.
Это потому, что в оригинальной разметке слово Tillie появилось перед точкой с запятой. Парсер обнаружил тег <a> , затем слово Tillie, затем закрывающий тег </a> , затем точку с запятой и оставшуюся часть предложения. Точка с запятой находится на том же уровне, что и тег <a> , но слово Tillie встретилось первым.
Атрибут .previous_element является полной противоположностью .next_element . Он указывает на элемент, который был обнаружен при разборе непосредственно перед текущим:
При помощи атрибутов .next_elements и .previous_elements можно получить список элементов, в том порядке, в каком он был разобран парсером.
Извлечение URL-адресов.
Одна из распространенных задач, это извлечение URL-адресов, найденных на странице в HTML-тегах <a> :
Извлечение текста HTML-страницы.
Другая распространенная задача — извлечь весь текст со HTML-страницы:
Поиск тегов по HTML-документу:
Найти первый совпавший HTML-тег можно методом BeautifulSoup.find() , а всех совпавших элементов — BeautifulSoup.find_all() .
Поиск тегов при помощи CSS селекторов:
Поиск тега под другими тегами:
Поиск тега непосредственно под другими тегами:
Поиск одноуровневых элементов:
Поиск тега по классу CSS:
Поиск тега по ID:
Дочерние элементы.
Извлечение НЕПОСРЕДСТВЕННЫХ дочерних элементов тега. Если посмотреть на HTML-разметку в коде ниже, то, непосредственными дочерними элементами первого <ul> будут являться три тега <li> и тег <ul> со всеми вложенными тегами.
Обратите внимание, что все переводы строк \n и пробелы между тегами, так же будут считаться дочерними элементами. Так что имеет смысл заранее привести исходный HTML к "нормальному виду", например так: re.sub(r'>\s+<', '><', html.replace('\n', ''))
Извлечение ВСЕХ дочерних элементов. Эта операция похожа на рекурсивный обход HTML-дерева в глубину от выбранного тега.
Обратите внимание, что простой текст, который находится внутри тега, так же считается дочерним элементом этого тега.
Если внутри тега есть более одного дочернего элемента (как в примерен выше) и необходимо извлечь только текст, то можно использовать атрибут .strings или генератор .stripped_strings .
Генератор .stripped_strings дополнительно удаляет все переводы строк \n и пробелы между тегами в исходном HTML-документе.
Родительские элементы.
Что бы получить доступ к родительскому элементу, необходимо использовать атрибут .parent .
Taк же можно перебрать всех родителей элемента с помощью атрибута .parents .
Изменение имен тегов HTML-документа:
Изменение HTML-тега <p> на тег <div> :
Добавление новых тегов в HTML-документ.
Добавление нового тега в дерево HTML:
Добавление новых тегов до/после определенного тега или внутрь тега.
Удаление и замена тегов в HTML-документе.
Удаляем тег или строку из дерева HTML:
Заменяем тег и/или строку в дереве HTML:
Изменение атрибутов тегов HTML-документа.
У тега может быть любое количество атрибутов. Тег <b > имеет атрибут id , значение которого равно boldest . Доступ к атрибутам тега можно получить, обращаясь с тегом как со словарем: