В этом руководстве вы изучите:
- Что такое AIOHTTP, и какие основные функции это средство предоставляет
- Пошаговый раздел об использовании AIOHTTP для веб-парсинга
- Передовые методы веб-парсинга с помощью AIOHTTP
- Сравнение AIOHTTP и Requests в сфере обработки автоматических запросов
Давайте рассмотрим эти вопросы подробнее!
Что такое AIOHTTP?
AIOHTTP — это асинхронный HTTP-фреймворк клиент-сервер, построенный на основе asyncio
на Python. В отличие от традиционных HTTP-клиентов, AIOHTTP использует сеансы клиентов для поддержания соединений для множества запросов. Это делает его эффективным средством для задач, основанных на сеансах с высоким уровнем параллелизма.
⚙️ Особенности
- Поддерживает как клиентские, так и серверные стороны протокола HTTP.
- Обеспечивает встроенную поддержку WebSockets (как для клиента, так и для сервера).
- Предлагает промежуточное ПО и подключаемую маршрутизацию для веб-серверов.
- Эффективно обрабатывает потоковую передачу больших данных.
- Включает сохранение сеанса клиента, позволяет повторно использовать соединение и снижает накладные расходы на выполнение множества запросов.
Парсинг с помощью AIOHTTP: пошаговое руководство
В контексте веб-парсинга AIOHTTP — это просто HTTP-клиент для получения необработанного HTML-контента страницы. Чтобы проанализировать HTML и извлечь из него данные, вам понадобится HTML-парсер, например BeautifulSoup.
Выполняйте инструкции в этом разделе, чтобы узнать, как использовать AIOHTTP для веб-парсинга с помощью BeautifulSoup!
Предупреждение: хотя AIOHTTP используется в основном на начальных этапах процесса, мы поможем вам пройти весь рабочий процесс парсинга. Если вас интересуют более продвинутые способы парсинга AIOHTTP, не стесняйтесь перейти к следующей главе после шага 3.
Шаг 1. Настройте свой проект по парсингу
Убедитесь, что на вашем компьютере установлен Python версии 3 или более новой. Если нет, скачайте его с официального сайта и следуйте инструкциям по установке.
Затем создайте каталог для проекта парсинга AIOHTTP, используя следующую команду:
mkdir aiohttp-scraper
Перейдите в этот каталог и настройте виртуальную среду:
cd aiohttp-scraper
python -m venv env
Откройте папку проекта в предпочитаемой среде Python IDE. Visual Studio Code с расширением Python или PyCharm Community Edition — подойдет оба этих варианта.
Теперь создайте файл scraper.py
в папке проекта. Сначала она будет пустая, но вскоре вы добавите в нее механизм парсинга.
В терминале своей IDE активируйте виртуальную среду. В Linux или macOS используйте:
./env/bin/activate
Аналогичным образом, в Windows запустите:
env/Scripts/activate
Отлично! У вас все настроено, и вы готовы к работе.
Шаг № 2. Настройка библиотек для парсинга
После активации виртуальной среды установите AIOHTTP и BeautifulSoup с помощью следующей команды:
pip install aiohttp beautifulsoup4
Это давбавит и aiohttp
, и beautifulsoup4
в число зависимых объектов вашего проекта.
Импортируйте их в свой скрипт scraper.py
:
import asyncio
import aiohttp
from bs4 import BeautifulSoup
Обратите внимание, что для работы aiohttp
требуется asyncio
.
Теперь добавьте следующий рабочий процесс функции async
в файл scrper.py
:
async def scrape_quotes():
# Scraping logic...
# Run the asynchronous function
asyncio.run(scrape_quotes())
scrape_quotes()
определяет асинхронную функцию, в которой ваш механизм очистки будет работать многопоточно без блокировок. Наконец, asyncio.run(scrape_quotes())
запускает и выполняет асинхронную функцию.
Потрясающе! Теперь можно перейти к следующему этапу рабочего процесса парсинга.
Шаг 3. Получение HTML-кода целевой страницы
Из этого примера вы узнаете, как собрать данные с сайта «Цитаты для парсинга»:
В таких библиотеках, как Requests или AIOHTTP вы просто отправите запрос GET и получите HTML-контент страницы напрямую. Однако у AIOHTTP иной жизненный цикл запроса.
Основным компонентом AIOHTTP является ClientSession
, который управляет пулом подключений и по умолчанию поддерживает Keep-Alive
. Вместо того чтобы открывать новое соединение для каждого запроса, оно повторно использует соединения, повышая производительность.
Процесс отправки запросаа обычно состоит из трех этапов:
- Открытие сеанса с помощью
clientSession()
. - Асинхронная отправка запроса GET с помощью
session.get()
. - Доступ к данным ответа с помощью таких методов, как
await response.text()
.
Такой механизм позволяет циклу событий использовать разные контексты with
между операциями без блокировки, что делает его идеальным выбором для задач с высоким уровнем параллелизма.
Учитывая это, вы можете использовать AIOHTTP для получения HTML-кода главной страницы с помощью следующей логики:
async with aiohttp.ClientSession() as session:
async with session.get("http://quotes.toscrape.com") as response:
# Access the HTML of the target page
html = await response.text()
AIOHTTP без отображения сведений о своих действиях отправляет запрос на сервер и ожидает ответа, содержащего HTML-код страницы. После получения ответа await response.text()
извлекает HTML-контент в виде строки.
Распечатайте переменную html
, и вы увидите:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Quotes to Scrape</title>
<link rel="stylesheet" href="/static/bootstrap.min.css">
<link rel="stylesheet" href="/static/main.css">
</head>
<body>
<!-- omitted for brevity... -->
</body>
</html>
Так держать! Вы успешно получили HTML-контент целевой страницы. Пришло время проанализировать этот контент и извлечь нужные данные.
Шаг 4. Парсинг HTML
Передайте HTML-контент в конструктор BeautifulSoup для его анализа:
# Parse the HTML content using BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
html.parser
— это HTML-парсер на Python по умолчанию, используемый для обработки контента.
Объект soup
содержит подвергнутый парсингу код HTML и предоставляет методы для извлечения необходимых данных.
AIOHTTP выполнил извлечение HTML, и теперь вы переходите к обычному этапу парсинга данных с помощью BeautifulSoup. Для получения более подробной информации прочитайте наше руководство по веб-парсингу BeautifulSoup.
Шаг 5. Напишите логический механизм извлечения данных
Парсинг данных цитат со страницы можно выполнить, используя следующий код:
# Where to store the scraped data
quotes = []
# Extract all quotes from the page
quote_elements = soup.find_all("div", class_="quote")
# Loop through quotes and extract text, author, and tags
for quote_element in quote_elements:
text = quote_element.find("span", class_="text").get_text().get_text().replace("“", "").replace("”", "")
author = quote_element.find("small", class_="author")
tags = [tag.get_text() for tag in quote_element.find_all("a", class_="tag")]
# Store the scraped data
quotes.append({
"text": text,
"author": author,
"tags": tags
})
Этот фрагмент инициализирует список под названием «цитаты»
, предназначенный для хранения данных, полученных в ходе парсинга. Затем он идентифицирует все HTML-элементы цитат и циклические просматривает их, чтобы извлечь текст цитаты, автора и теги. Каждая извлеченная цитата хранится в виде словаря в списке «цитаты»
, в котором данные упорядочены для последующего использования или экспорта.
Великолепно! Логический механизм парсинга создан.
Шаг 6. Экспорт данных, полученных в ходе парсинга
Используйте следующие строки кода для экспорта данных, полученных в ходе парсинга, в CSV-файл:
# Open the file for export
with open("quotes.csv", mode="w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=["text", "author", "tags"])
# Write the header row
writer.writeheader()
# Write the scraped quotes data
writer.writerows(quotes)
Приведенный выше фрагмент открывает файл с именем quotes.csv
в режиме записи. Затем он настраивает заголовки столбцов (текст
, автор
, теги
), записывает заголовки, а затем записывает каждый словарь из списка «цитаты»
в CSV-файл.
csv.DictWriter
упрощает форматирование данных, что делает проще хранение структурированных данных. Чтобы все заработало, не забудьте импортировать csv
из стандартной библиотеки Python:
import csv
Шаг 7. Заключительная сборка
Вот как должен выглядеть ваш последний скрипт для веб-парсинга с помощью AIOHTTP:
import asyncio
import aiohttp
from bs4 import BeautifulSoup
import csv
# Define an asynchronous function to make the HTTP GET request
async def scrape_quotes():
async with aiohttp.ClientSession() as session:
async with session.get("http://quotes.toscrape.com") as response:
# Access the HTML of the target page
html = await response.text()
# Parse the HTML content using BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
# List to store the scraped data
quotes = []
# Extract all quotes from the page
quote_elements = soup.find_all("div", class_="quote")
# Loop through quotes and extract text, author, and tags
for quote_element in quote_elements:
text = quote_element.find("span", class_="text").get_text().replace("“", "").replace("”", "")
author = quote_element.find("small", class_="author").get_text()
tags = [tag.get_text() for tag in quote_element.find_all("a", class_="tag")]
# Store the scraped data
quotes.append({
"text": text,
"author": author,
"tags": tags
})
# Open the file name for export
with open("quotes.csv", mode="w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=["text", "author", "tags"])
# Write the header row
writer.writeheader()
# Write the scraped quotes data
writer.writerows(quotes)
# Run the asynchronous function
asyncio.run(scrape_quotes())
Вы можете запустить его с помощью:
python scraper.py
Или в Linux/macOS:
python3 scraper.py
Файл quotes.csv
появится в корневой папке вашего проекта. Откройте его, и вы увидите:
Все готово! Вы только что узнали, как выполнять веб-парсинг с помощью AIOHTTP и BeautifulSoup.
AIOHTTP для веб-парсинга: расширенные функции и методы
Теперь, когда вы понимаете, как использовать AIOHTTP для базового веб-парсинга, пришло время рассмотреть более сложные сценарии.
В следующих примерах целевым сайтом будет конечная точка HTTPBin.io /anything
. Это удобный API, который возвращает IP-адрес, заголовки и другие данные, отправленные запрашивающей стороной.
Приготовьтесь освоить AIOHTTP для веб-парсинга!
Настройка пользовательских заголовков
Вы можете указать собственные заголовки в запросе AIOHTTP с аргументом headers
:
import aiohttp
import asyncio
async def fetch_with_custom_headers():
# Custom headers for the request
headers = {
"Accept": "application/json",
"Accept-Language": "en-US,en;q=0.9,fr-FR;q=0.8,fr;q=0.7,es-US;q=0.6,es;q=0.5,it-IT;q=0.4,it;q=0.3"
}
async with aiohttp.ClientSession() as session:
# Make a GET request with custom headers
async with session.get("https://httpbin.io/anything", headers=headers) as response:
data = await response.json()
# Handle the response...
print(data)
# Run the event loop
asyncio.run(fetch_with_custom_headers())
Таким образом, AIOHTTP отправит HTTP-запрос GET с заданными заголовками Accept
и Accept-Language
.
Настройка особого пользовательского агента
User-Agent
— один из наиболее важных HTTP-заголовков для веб-парсинга. По умолчанию AIOHTTP использует следующий пользовательский агент
:
Python/<PYTHON_VERSION> aiohttp/<AIOHTTP_VERSION>
Приведенное выше значение по умолчанию может легко показать, что ваши запросы поступают из автоматического скрипта. Это повысит риск блокировки целевым сайтом.
Чтобы снизить вероятность обнаружения, вы можете настроить собственный реальный пользовательский агент
, как и раньше:
import aiohttp
import asyncio
async def fetch_with_custom_user_agent():
# Define a Chrome-like custom User-Agent
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"
}
async with aiohttp.ClientSession(headers=headers) as session:
# Make a GET request with the custom User-Agent
async with session.get("https://httpbin.io/anything") as response:
data = await response.text()
# Handle the response...
print(data)
# Run the event loop
asyncio.run(fetch_with_custom_user_agent())
Узнайте про лучшие пользовательские агенты для веб-парсинга!
Установка файлов cookie
Как и в HTTP-заголовках, вы можете настроить пользовательские файлы cookie, используя файлы cookie
в СlientSession()
:
import aiohttp
import asyncio
async def fetch_with_custom_cookies():
# Define cookies as a dictionary
cookies = {
"session_id": "9412d7hdsa16hbda4347dagb",
"user_preferences": "dark_mode=false"
}
async with aiohttp.ClientSession(cookies=cookies) as session:
# Make a GET request with custom cookies
async with session.get("https://httpbin.io/anything") as response:
data = await response.text()
# Handle the response...
print(data)
# Run the event loop
asyncio.run(fetch_with_custom_cookies())
Файлы cookie помогают включать необходимые данные сеанса в запросы веб-парсинга.
Обратите внимание, что файлы cookie, установленные в ClientSession
, используются для всех запросов, сделанных в этом сеансе. Чтобы получить доступ к сеансовым файлам cookie, обратитесь к ClientSession.cookie_jar
.
Интеграция прокси-серверов
В AIOHTTP вы можете направлять запросы через прокси-сервер, чтобы снизить риск блокировки IP-адресов. Для этого используйте аргумент proxy
в функции HTTP-метода в сеансе
:
import aiohttp
import asyncio
async def fetch_through_proxy():
# Replace with the URL of your proxy server
proxy_url = "<YOUR_PROXY_URL>"
async with aiohttp.ClientSession() as session:
# Make a GET request through the proxy server
async with session.get("https://httpbin.io/anything", proxy=proxy_url) as response:
data = await response.text()
# Handle the response...
print(data)
# Run the event loop
asyncio.run(fetch_through_proxy())
Узнайте, как выполнять аутентификацию и ротацию прокси-серверов, из нашего руководства по использованию прокси в AIOHTTP.
Обработка ошибок
По умолчанию AIOHTTP вызывает ошибки только из-за проблем с подключением или сетью. Чтобы создать исключения для HTTP-ответов при получении кодов состояния 4xx
и 5xx
, вы можете использовать любой из следующих подходов:
- Задайте
raise_for_status=True
при созданииClientSession
: автоматически создавать исключения для всех запросов, сделанных в сеансе, если статус ответа равен4xx
или5xx
. - Передайте
raise_for_status=True
непосредственно методам запроса: включите выдачу ошибок для отдельных методов запроса (например,session.get()
илиsession.post()
), не затрагивая другие. - Вызовите
response.raise_for_status()
вручную: дайте полный контроль над тем, когда создавать исключения, и принимать решения по каждому запросу.
Пример варианта №1:
import aiohttp
import asyncio
async def fetch_with_session_error_handling():
async with aiohttp.ClientSession(raise_for_status=True) as session:
try:
async with session.get("https://httpbin.io/anything") as response:
# No need to call response.raise_for_status(), as it is automatic
data = await response.text()
print(data)
except aiohttp.ClientResponseError as e:
print(f"HTTP error occurred: {e.status} - {e.message}")
except aiohttp.ClientError as e:
print(f"Request error occurred: {e}")
# Run the event loop
asyncio.run(fetch_with_session_error_handling())
Если на уровне сеанса установлено значение raise_for_status=True
, все запросы, отправленные в этом сеансе, вызовут ошибку aiohttp.ClientResponseError
для ответов 4xx
или 5xx
.
Пример варианта №2:
import aiohttp
import asyncio
async def fetch_with_raise_for_status():
async with aiohttp.ClientSession() as session:
try:
async with session.get("https://httpbin.io/anything", raise_for_status=True) as response:
# No need to manually call response.raise_for_status(), it is automatic
data = await response.text()
print(data)
except aiohttp.ClientResponseError as e:
print(f"HTTP error occurred: {e.status} - {e.message}")
except aiohttp.ClientError as e:
print(f"Request error occurred: {e}")
# Run the event loop
asyncio.run(fetch_with_raise_for_status())
В этом случае аргумент raise_for_status=True
передается непосредственно в вызов session.get()
. Это гарантирует автоматическое создание исключения для любых кодов состояния 4xx
или 5xx
.
Пример варианта №3:
import aiohttp
import asyncio
async def fetch_with_manual_error_handling():
async with aiohttp.ClientSession() as session:
try:
async with session.get("https://httpbin.io/anything") as response:
response.raise_for_status() # Manually raises error for 4xx/5xx
data = await response.text()
print(data)
except aiohttp.ClientResponseError as e:
print(f"HTTP error occurred: {e.status} - {e.message}")
except aiohttp.ClientError as e:
print(f"Request error occurred: {e}")
# Run the event loop
asyncio.run(fetch_with_manual_error_handling())
Если вы предпочитаете больше контролировать отдельные запросы, вы можете вызвать response.raise_for_status()
вручную после отправки запроса. Такой подход позволяет вам точно решить, когда следует обрабатывать ошибки.
Повтор неудачных запросов
AIOHTTP не предоставляет встроенной поддержки автоматической повторной отправки запросов. Чтобы реализовать это, вы должны использовать собственную логику или стороннюю библиотеку, такую как aiohttp-retry
. Она позволяет настроить логику повторных попыток для неудачных запросов, что поможет решить временные проблемы с сетью, таймаутами или ограничениями скорости.
Установите aiohttp-retry
с помощью:
pip install aiohttp-retry
Затем вы можете использовать ее следующим образом:
import asyncio
from aiohttp_retry import RetryClient, ExponentialRetry
async def main():
retry_options = ExponentialRetry(attempts=1)
retry_client = RetryClient(raise_for_status=False, retry_options=retry_options)
async with retry_client.get("https://httpbin.io/anything") as response:
print(response.status)
await retry_client.close()
Это настраивает поведение при повторных попытках с использованием стратегии экспоненциального прерывания. Узнайте больше в официальных документах.
AIOHTTP и запросы на веб-парсинг
Ниже приведена сводная таблица для сравнения запросов AIOHTTP и Requests при веб-парсинге:
Особенности | AIOHTTP | Requests |
---|---|---|
Звезды на GitHub | 15,3 тыс. | 52,4 тыс. |
Поддержка клиентов | ✔️ | ✔️ |
Поддержка синхронизации | ❌ | ✔️ |
Поддержка асинхронного режима | ✔️ | ❌ |
Поддержка серверов | ✔️ | ❌ |
Пул соединений | ✔️ | ✔️ |
/Поддержка HTTP/2 | ❌ | ❌ |
Настройка пользовательского агента | ✔️ | ✔️ |
Поддержка прокси-сервера | ✔️ | ✔️ |
Обработка файлов cookie | ✔️ | ✔️ |
Механизм повторов | Доступность только через стороннюю библиотеку | Доступно через HTTPAdapter s |
Производительность | Высокая | Средняя |
Поддержка сообщества и популярность | Средняя | Большая |
Для полного сравнения ознакомьтесь с нашей публикацией в блоге со сравнением Requests, HTTPX и AIOHTTP.
Узнайте, как выполнять парсинг веб-сайтов с помощью HTTPX.
Заключение
Из этой статьи вы узнали, как использовать библиотеку aiohttp
для веб-парсинга. Вы узнали, что это такое, какие функции и преимущества она предлагает. AIOHTTP — это быстрый и надежный выбор для HTTP-запросов при сборе онлайн-данных.
Однако автоматические HTTP-запросы отображают ваш публичный IP-адрес. Это может раскрыть вашу личность и местоположение, что поставит под угрозу вашу конфиденциальность. Чтобы обеспечить вашу безопасность и конфиденциальность, одной из наиболее эффективных стратегий является использование прокси-сервера для сокрытия своего IP-адреса.
Bright Data контролирует лучшие прокси-серверы в мире, обслуживая компании из списка Fortune 500 и более 20 000 клиентов. Предложение компании включает в себя широкий ассортимент прокси-серверов различных типов:
- Прокси центров обработки данных — более 770 000 IP-адресов центров обработки данных.
- Резидентные прокси-серверы — более 72 млн резидентных IP-адресов в более чем 195 странах.
- Прокси-серверы интернет-провайдеров — более 700 000 IP-адресов интернет-провайдеров.
- Мобильные прокси-серверы — более 7 млн мобильных IP-адресов.
Создайте бесплатную учетную запись Bright Data сегодня, чтобы протестировать наши прокси-серверы и решения для парсинга!
Кредитная карта не требуется