Веб-скрейпинг с помощью Python: учебник по HTML-парсеру BeautifulSoup
Введение
Web scraping - это техника, используемая для извлечения большого количества данных с веб-сайтов и их форматирования для использования в различных приложениях. Веб-скрейпинг позволяет нам автоматически извлекать данные и представлять их в пригодной для использования конфигурации или обрабатывать и хранить данные в другом месте. Собранные данные также могут быть частью конвейера, где они рассматриваются как входные данные для других программ.
В прошлом извлечение информации с веб-сайта означало копирование текста, имеющегося на веб-странице, вручную. Этот метод крайне неэффективен и не масштабируется. В наши дни в Python есть несколько замечательных пакетов, которые помогут нам автоматизировать этот процесс! В этом посте я расскажу о некоторых случаях использования веб-скрейпинга, выделю наиболее популярные пакеты с открытым исходным кодом и приведу пример проекта по соскабливанию общедоступных данных на Github.
Случаи использования веб-скрапинга
При эффективном использовании веб-скрейпинг является мощным инструментом сбора данных. Некоторые примеры областей, в которых применяется веб-скрейпинг, следующие:
- Поиск: Поисковые системы используют веб-скрейпинг для индексации веб-сайтов, чтобы они появлялись в результатах поиска. Чем лучше техника скраппинга, тем точнее результаты.
- Тенденции: В сфере коммуникаций и СМИ веб-скрейпинг может использоваться для отслеживания последних тенденций и историй, поскольку не хватает рабочей силы для освещения каждой новой истории или тенденции. С помощью веб-скрейпинга можно добиться большего в этой области.
- Брендинг: Веб-скрейпинг также позволяет командам по коммуникациям и маркетингу соскабливать информацию о присутствии их бренда в Интернете. Поиск отзывов о вашем бренде позволит вам узнать, что люди думают или чувствуют о вашей компании, и разработать на основе этой информации стратегии взаимодействия и вовлечения.
- Машинное обучение: Веб-скрейпинг чрезвычайно полезен для добычи данных для построения и обучения моделей машинного обучения.
- Финансы: Может быть полезно соскабливать данные, которые могут повлиять на движения на фондовом рынке. Хотя существуют некоторые онлайн-агрегаторы, создание собственного пула сбора данных позволяет управлять задержками и обеспечивать правильную категоризацию или приоритезацию данных.
Инструменты и библиотеки
Существует несколько популярных онлайн-библиотек, которые предоставляют программистам инструменты для быстрого создания собственного скрепера. Некоторые из моих любимых включают:
Requests
- библиотека для отправки HTTP-запросов, которая очень популярна и проще в использовании по сравнению со стандартной библиотекойurllib
.BeautifulSoup
- библиотека парсинга, которая использует различные парсеры для извлечения данных из HTML и XML документов. Она способна перемещаться по разобранному документу и извлекать то, что требуется.Scrapy
- фреймворк Python, который изначально был разработан для веб-скрейпинга, но все чаще используется для извлечения данных с помощью API или в качестве веб-краулера общего назначения. Он также может использоваться для работы с конвейерами вывода. С помощьюscrapy
вы можете создать проект с несколькими скреперами. Он также имеет режим оболочки, в котором вы можете экспериментировать с его возможностями.lxml
- предоставляет привязку к python для быстрой библиотеки обработки html и xml под названиемlibxml
. Может использоваться отдельно для парсинга сайтов, но требует больше кода для корректной работы по сравнению сBeautifulSoup
. Используется внутри парсераBeautifulSoup
.Selenium
- фреймворк автоматизации браузера. Используется при разборе данных с динамически изменяющихся веб-страниц, когда необходимо имитировать работу браузера.
Library | Learning curve | Can fetch | Can process | Can run JS | Performance |
requests |
easy | yes | no | no | fast |
BeautifulSoup4 |
easy | no | yes | no | normal |
lxml |
medium | no | yes | no | fast |
Selenium |
medium | yes | yes | yes | slow |
Scrapy |
hard | yes | yes | no | normal |
Использование парсера HTML на Github
Мы будем использовать библиотеку BeautifulSoup
для создания простого веб-скрепера для Github. Я выбрал BeautifulSoup
, потому что это простая библиотека для извлечения данных из HTML и XML файлов с легкой кривой обучения и относительно небольшими усилиями. Она предоставляет удобную функциональность для обхода дерева DOM в HTML-файле с помощью вспомогательных функций
Требования
В этом руководстве я предполагаю, что у вас есть машина на базе Unix или Windows. Вам также потребуется установить на машине следующее:
- Python 3
BeautifulSoup4
Библиотека
Профилирование веб-страницы
Сначала нам нужно решить, какую информацию мы хотим собрать. В данном случае я надеюсь получить список репозиториев пользователя вместе с их названиями, описаниями и основным языком программирования. Для этого мы воспользуемся Github, чтобы получить подробную информацию о репозиториях пользователя. Хотя эта информация доступна через API Github, самостоятельный поиск данных позволит нам лучше контролировать формат и полноту конечных данных.
После этого мы составим профиль сайта, чтобы увидеть, где находится наша целевая информация, и создать план по ее извлечению.
Чтобы составить профиль веб-сайта, посетите веб-страницу и осмотрите ее, чтобы узнать расположение элементов.
Для примера посетим профиль Github Гвидо ван Россума и посмотрим его репозитории:
div
, содержащий список репозиториев Из скриншота выше мы можем сказать, что список репозиториев пользователя находится вdiv
под названиемuser-repositories-list
, поэтому именно он будет в центре нашего внимания. Этот div содержит элементы списка, которые являются списком репозиториев.- Элемент списка, содержащий информацию об одном репозитории / соответствующую информацию о DOM-дереве Следующая часть показывает нам расположение элемента списка, содержащего информацию об одном репозитории. Мы также можем увидеть этот раздел, как он отображается на дереве DOM.
- Расположение имени и ссылки репозитория Внутри одного элемента списка есть ссылка
href
, которая содержит имя и ссылку репозитория. - Расположение описания хранилища
- Местонахождение языка хранилища
Для нашего простого скрепера мы извлечем название репозитория, описание, ссылку и язык программирования.
Настройка скрепера
Сначала мы настроим нашу виртуальную среду, чтобы изолировать нашу работу от остальной системы, а затем активируем среду. Введите следующие команды в оболочке или командной строке:
mkdir scraping-example
cd scraping-example
Если вы используете Mac, вы можете использовать эту команду для активации виртуальной среды:
python -m venv venv-scraping
В Windows виртуальная среда активируется следующей командой:
venv-scraping\Scripts\activate.bat
Наконец, установите необходимые пакеты:
pip install bs4 requests
Первый пакет, requests
, позволит нам запрашивать веб-сайты и получать HTML-содержимое веб-сайта в том виде, в котором оно отображается в браузере. Именно это HTML-содержимое наш скрепер будет просматривать и находить нужную нам информацию.
Второй пакет, BeautifulSoup4
, позволит нам просмотреть содержимое HTML, затем найти и извлечь необходимую информацию. Он позволяет искать содержимое по тегам HTML, элементам и именам классов, используя встроенный модуль синтаксического анализатора Python.
Функция простого скребка
Наша функция запросит веб-сайт с помощью requests
и вернет его HTML-содержимое.
Следующим шагом будет использование библиотеки BeautifulSoup
для просмотра HTML и извлечения div, который, как мы определили, содержит элементы списка в хранилищах пользователя. Затем мы пройдемся по элементам списка и извлечем из них как можно больше информации для нашего использования.
# The function to scrape a website
def scrape_website(url):
# query the web page
response = requests.get(url)
# parse the fetched HTML content using a HTML parser
# since our page content is going to be in HTML format
soup = BeautifulSoup(response.content, 'HTML.parser')
# find the repositories container div
main_content = soup.find('div', {'id': 'user-repositories-list'})
# Extract the list of repositories
list_or_repos = main_content.findAll('li')
# create a new list to put our extracted data
results = []
# Function to extract the details for each repo
for repo in list_of_repos:
# create a new repo's details dictionary
repository = {}
# add the repository name, note that we strip a leading newline and
# leading and trailing whitespaces
repository['name'] = repo.a.string.strip()
# Extract the base url for the url passed into the function
base_url = '{uri.scheme}://{uri.netloc}'.format(uri=urlparse(url))
# generate the repository link
repository['link'] = '{0}{1}'.format(base_url, repo.a.get('href'))
# Check if there is a repo description and add it to our dictionary
if repo.p and repo.p.string:
repository['description'] = repo.p.string.strip()
# if no description is found
else:
repository['description'] = 'No description available for this repository.'
# add the programming language of the repository
programming_language = soup.find(attrs={'itemprop':'programmingLanguage'}).string.strip()
repository['programming_language'] = programming_language
# add our repo to our results
results.append(repository)
# return our list of repositories as the output of our function
return results
# Try it out
print(json.dumps(scrape_website('https://github.com/gvanrossum?tab=repositories'), indent=4))
Вы, наверное, заметили, как мы извлекли язык программирования. BeautifulSoup
позволяет нам искать информацию не только с помощью элементов HTML, но и с помощью атрибутов элементов HTML. Это простой трюк для повышения точности при работе с наборами данных, связанных с программированием.
Result
Вот и все! Вы успешно создали свой Github Repository Scraper и можете протестировать его на множестве репозиториев других пользователей. Вы можете проверить Github-репозиторий Kite, чтобы легко получить доступ к коду из этого поста и других из их Python серии.
Теперь, когда вы создали этот скрепер, существует огромное количество возможностей для его усовершенствования и использования. Например, этот скрепер может быть модифицирован для отправки уведомления, когда пользователь добавляет новый репозиторий. Это позволит вам быть в курсе последних работ разработчика. (Помните, я упоминал, что инструменты скраппинга полезны в финансовой сфере? Ведение собственного скрапера и настройка уведомлений о новых данных были бы очень полезны в этой области).
Другая идея заключается в создании расширения для браузера, которое отображает репозитории пользователя при наведении на любую страницу на Github. Скрепер будет передавать данные в API, который обслуживает расширение. Затем эти данные будут передаваться и отображаться в расширении. Вы также можете создать инструмент сравнения пользователей Github на основе данных, которые вы соскабливаете, создавая рейтинг на основе того, насколько активно пользователи обновляют свои репозитории, или используя определение ключевых слов для поиска репозиториев, которые вам нужны.
Что дальше?
В этой заметке мы рассмотрели основы веб-скрейпинга и затронули лишь некоторые из многочисленных вариантов его использования. requests
и beautifulsoup
являются мощными и относительно простыми инструментами для веб-скрейпинга, но вы также можете ознакомиться с некоторыми более продвинутыми библиотеками, которые я выделил в начале статьи, для еще большей функциональности. Следующим шагом будет создание более сложных скреперов, которые могут состоять из множества функций скрепирования из разных источников. Существует бесконечное множество способов интеграции этих скреперов в любой проект, который может получить пользу от данных, общедоступных в Интернете. В конце концов, у вас будет столько функций веб-скрейпинга, что вам придется задуматься о переносе своих вычислений на домашний сервер или в облако!