Разработчики Python имеют дос? ... Какие лучшие библиотеки для парсинга на языке Python?
Какие лучшие библиотеки для парсинга на языке Python?...
Разработчики Python имеют доступ к некоторым из лучших библиотек и фреймворков для парсинга. Узнайте, как они работают на практике и как их выбирать.
Введение
Парсинг — это, по сути, способ автоматизации процесса извлечения данных из Интернета, и, будучи разработчиком на Python, вы имеете доступ к некоторым из лучших библиотек и фреймворков, которые помогут вам выполнить эту работу. Мы рассмотрим некоторые из наиболее популярных библиотек и фреймворков Python для парсинга и сравним их плюсы и минусы, чтобы вы точно знали, какой инструмент использовать для любого проекта парсинга, с которым вы можете столкнуться.
Библиотеки HTTP — запросы и HTTPX
Прежде всего, давайте поговорим о библиотеках HTTP. Они являются основой парсинга, поскольку любая работа по парсингу начинается с выполнения запроса к веб-сайту и получения его содержимого, обычно в виде HTML. Две популярные библиотеки HTTP в Python — это Requests и HTTPX. Requests проста в использовании и отлично подходит для простых задач парсинга, в то время как HTTPX предлагает некоторые расширенные возможности, такие как async и поддержка HTTP/2. Их основная функциональность и синтаксис очень похожи, поэтому я бы рекомендовал HTTPX даже для небольших проектов, поскольку в будущем вы сможете легко расширить возможности без ущерба для производительности.
Характеристика | HTTPX | Запросы |
Асинхронный | Да | Нет |
HTTP/2 support | Да | Нет |
Timeout support | Да | Да |
Proxy support | Да | Да |
TLS verification | Да | Да |
Пользовательские исключения | Да | Нет |
Разбор HTML с помощью Beautiful Soup
Когда у вас есть HTML-содержимое, вам нужен способ разобрать его и извлечь интересующие вас данные. Beautiful Soup — самый популярный парсер HTML в Python, позволяющий легко перемещаться и искать по древовидной структуре HTML. Простой синтаксис и легкая настройка делают Beautiful Soup отличным вариантом для небольших и средних проектов по парсингу, а также для начинающих парсеров. Двумя основными недостатками Beautiful Soup являются его неспособность парсить сайты с JavaScript и ограниченная масштабируемость, что приводит к низкой производительности в крупных проектах. Для крупных проектов лучше использовать Scrapy, но об этом подробнее позже.
Далее рассмотрим, как работает Beautiful Soup на практике:
from bs4 import BeautifulSoup import httpx # Send an HTTP GET request to the specified URL using the httpx library response = httpx.get("<https://news.ycombinator.com/news>") # Save the content of the response yc_web_page = response.content # Use the BeautifulSoup library to parse the HTML content of the webpage soup = BeautifulSoup(yc_web_page) # Find all elements with the class "athing" (which represent articles on Hacker News) using the parsed HTML articles = soup.find_all(class_="athing") # Loop through each article and extract relevant data, such as the URL, title, and rank for article in articles: data = { "URL": article.find(class_="titleline").find("a").get('href'), # Find the URL of the article by finding the first "a" tag within the element with class "titleline" "title": article.find(class_="titleline").getText(), # Find the title of the article by getting the text content of the element with class "titleline" "rank": article.find(class_="rank").getText().replace(".", "") # Find the rank of the article by getting the text content of the element with class "rank" and removing the period character } # Print the extracted data for the current article print(data)
Объяснение кода:
- Мы начинаем с отправки HTTP GET запроса на указанный URL с помощью библиотеки HTTPX. Затем мы сохраняем полученное содержимое в переменную.
- Теперь мы используем библиотеку Beautiful Soup для разбора HTML-содержимого веб-страницы.
- Это позволяет нам манипулировать разобранным содержимым с помощью методов Beautiful Soup, таких как find_all, чтобы найти нужное нам содержимое. В данном конкретном случае мы находим все элементы с классом athing, который представляет статьи на Hacker News.
- Далее мы просто перебираем все статьи на странице, а затем используем селекторы CSS, чтобы уточнить, какие данные мы хотим извлечь из каждой статьи. Наконец, мы выводим полученные данные в консоль.
Библиотеки автоматизации браузера — Selenium и Playwright
Что если сайт, который вы собираетесь изучить, использует JavaScript для загрузки своего содержимого? В этом случае HTML-парсера будет недостаточно, так как вам нужно будет создать экземпляр браузера для загрузки JavaScript страницы с помощью инструмента автоматизации браузера, например Selenium или Playwright. В первую очередь это инструменты тестирования и автоматизации, которые позволяют программно управлять веб-браузером, включая нажатие кнопок, заполнение форм и многое другое. Однако они также часто используются в веб-парсинге как средство доступа к динамически генерируемым данным на веб-странице.
Хотя Selenium и Playwright очень похожи по своей основной функциональности, Playwright является более современным и полным, чем Selenium. Например, Playwright предлагает некоторые уникальные встроенные функции, такие как автоматическое ожидание отображения элементов перед выполнением действий и асинхронную версию API с использованием asyncIO. Для примера того, как можно использовать Playwright для парсинга, давайте быстро пройдемся по фрагменту кода, в котором мы используем Playwright для извлечения данных из продукта Amazon и сохранения скриншота страницы при этом.
import asyncio from playwright.async_api import async_playwright async def main(): async with async_playwright() as p: browser = await p.firefox.launch(headless=False) page = await browser.new_page() await page.goto("<https://www.amazon.com/Hitchhikers-Guide-Galaxy-Douglas-Adams-ebook/dp/B000XUBC2C>") # Create a dictionary with the scraped data selectors = ['#productTitle', 'span.author a', '#productSubtitle', '.a-size-base.a-color-price.a-color-price'] book_data = await asyncio.gather(*(page.query_selector(sel) for sel in selectors)) book = {} book["book_title"], book["author"], book["edition"], book["price"] = [await elem.inner_text() for elem in book_data if elem] print(book) await page.screenshot(path="book.png") await browser.close() asyncio.run(main())
Объяснение кода:
- Импортируйте необходимые модули: asyncio и async_playwright из асинхронного API Playwright.
- После импорта необходимых модулей мы начинаем с определения асинхронной функции main, которая запускает экземпляр браузера Firefox с режимом headless mode, установленным на False, чтобы мы могли видеть работу браузера. Создает новую страницу в браузере с помощью метода new_page и, наконец, переходит на сайт Amazon с помощью метода gotomethod.
- Далее мы определяем список селекторов CSS для данных, которые мы хотим получить. Затем с помощью метода asyncio.gather мы можем одновременно выполнить метод page.query_selector для всех селекторов в списке и сохранить результаты в переменной book_data.
- Теперь мы можем выполнять итерации над book_data, чтобы заполнить словарь книг полученными данными. Обратите внимание, что мы также проверяем, что элемент не является None, и добавляем только те элементы, которые существуют. Это считается хорошей практикой, поскольку веб-сайты могут внести небольшие изменения, которые повлияют на ваш парсер. Вы можете даже расширить этот пример и написать более сложные тесты, чтобы убедиться, что в извлекаемых данных не пропущены какие-либо значения.
- Наконец, мы выводим содержимое словаря книги в консоль и делаем снимок экрана спарсенной страницы, сохраняя его в файл book.png.
- В качестве последнего шага мы обязательно закрываем экземпляр браузера.
Но подождите! Если инструменты автоматизации браузера могут быть использованы для парсинга практически любой веб-страницы и, кроме того, облегчают автоматизацию задач, тестирование и визуализацию работы кода, почему бы нам просто не использовать Playwright или Selenium для парсинга?
Ну, несмотря на то, что эти библиотеки и фреймворки являются мощными инструментами для парсинга, у них есть заметный недостаток. Оказывается, создание экземпляра браузера — это очень ресурсоемкое действие по сравнению с простым получением HTML страницы. Это может легко стать серьезным узким местом в производительности при выполнении больших заданий по парсингу, которые не только будут выполняться дольше, но и станут значительно дороже. По этой причине мы обычно хотим ограничить использование этих инструментов только необходимыми задачами и, по возможности, использовать их вместе с Beautiful Soup или Scrapy.
Scrapy
Далее у нас самый популярный и, возможно, мощный фреймворк для парсинга на Python. Если вам необходимо регулярно спарсить большие объемы данных, то Scrapy может стать отличным вариантом. Фреймворк Scrapy предлагает полный набор инструментов, которые помогут вам даже в самых сложных задачах. Помимо превосходной производительности по сравнению с Beautiful Soup, Scrapy легко интегрируется в другие инструменты Python для обработки данных и даже в другие библиотеки, такие как Playwright. Кроме того, он поставляется с удобной коллекцией встроенных функций, предназначенных специально для парсинга, таких как:
Характеристика | Описание |
Мощная и гибкая система спайдинга | Scrapy предоставляет встроенную структуру паутины, которая позволяет легко определять и настраивать веб-краулеры для извлечения нужных вам данных. |
Быстро и эффективно | Scrapy разработан для быстрой и эффективной работы, позволяя вам извлекать данные из больших веб-сайтов быстро и с минимальным использованием ресурсов. |
Поддержка работы с распространенными форматами веб-данных | Экспорт данных в несколько форматов, таких как HTML, XML и JSON. |
Расширяемая архитектура | Легко добавляйте пользовательские функции с помощью промежуточного ПО, конвейеров и расширений. |
Распределенное парсбукинг | Scrapy поддерживает распределенный парсинг, позволяя вам масштабировать операции парсинга на нескольких машинах. |
Обработка ошибок | Scrapy обладает мощными возможностями обработки ошибок, позволяя вам обрабатывать распространенные ошибки и исключения, которые могут возникнуть во время веб-парсинга. |
Поддержка аутентификации и файлов cookie | Поддерживает обработку аутентификации и файлов cookie для парсинга веб-сайтов, требующих учетных данных для входа. |
Интеграция с другими инструментами Python | Scrapy легко интегрируется с другими инструментами Python, такими как библиотеки для обработки и хранения данных, что делает его мощным инструментом для сквозных конвейеров обработки данных. |
Вот пример того, как использовать Scrapy Spider для парсинга данных с веб-сайта:
import scrapy class HackernewsSpiderSpider(scrapy.Spider): name = 'hackernews_spider' allowed_domains = ['news.ycombinator.com'] start_urls = ['<http://news.ycombinator.com/>'] def parse(self, response): articles = response.css('tr.athing') for article in articles: yield { "URL": article.css(".titleline a::attr(href)").get(), "title": article.css(".titleline a::text").get(), "rank": article.css(".rank::text").get().replace(".", "") }
Мы можем использовать следующую команду для запуска этого сценария и сохранения полученных данных в файл JSON:
scrapy crawl hackernews -o hackernews.json
Объяснение кода:
В примере кода используется Scrapy для парсинга данных с сайта Hacker News (news.ycombinator.com). Давайте разберем код шаг за шагом:
После импорта необходимых модулей мы определяем класс Spider, который мы хотим использовать:
class HackernewsSpiderSpider(scrapy.Spider):
Далее мы задаем свойства паука:
- Name: Имя паука (используется для его идентификации).
- Разрешенные_домены: Список доменов, которые пауку разрешено просматривать.
- Start_urls: Список URL-адресов, с которых будет начинаться сканирование.
name = 'hackernews_spider' allowed_domains = ['news.ycombinator.com'] start_urls = ['<http://news.ycombinator.com/>']
Затем мы определяем метод parse: Этот метод является точкой входа для паука и вызывается с ответом URL, указанным в start_urls.
def parse(self, response):
В методе parse мы будем извлекать данные из HTML-ответа: Объект ответа представляет собой HTML-страницу, полученную с веб-сайта. Паук использует селекторы CSS для извлечения соответствующих данных из структуры HTML.
articles = response.css('tr.athing')
Теперь мы используем цикл for для перебора каждой статьи, найденной на странице.
for article in articles:
Наконец, для каждой статьи паук извлекает URL, заголовок и информацию о рейтинге с помощью селекторов CSS и создает словарь Python, содержащий эти данные.
yield { "URL": article.css(".titleline a::attr(href)").get(), "title": article.css(".titleline a::text").get(), "rank": article.css(".rank::text").get().replace(".", "") }
Какая библиотека Python для парсинга подходит вам?
Итак, какую библиотеку следует использовать для вашего проекта парсинга? Ответ зависит от конкретных нужд и требований вашего проекта. Каждая из представленных здесь библиотек и фреймворков для парсинга имеет свое уникальное назначение в наборе инструментов эксперта-парсера. Научившись использовать каждую из них, вы сможете выбрать лучший инструмент для каждой работы, поэтому не бойтесь попробовать каждую из них, прежде чем принять решение!