Заголовки (HTTP headers) играют важную роль в процессе взаимодействия между сервером и клиентом через протокол HTTP. Представляют собой набор метаданных, который добавляется к HTTP-запросам и ответам. Обеспечивают решение различных задач – обеспечение безопасности, отслеживание ошибок, разбирать основные данные, управлять сессиями и так далее.
При разработке парсера рекомендуется вместе с GET-запросом отправлять собственные заголовки, это расширяет возможности. Сервер может получать информацию, что делать с текущим запросом. Также заголовки позволяют обходить блокировки, маскируясь под обычный браузер (cookie, User-Agent, IP).
Основные типы заголовков
Заголовки запроса (Request Headers). Присутствуют только в HTTP-запросах. Могут содержать информацию о клиенте, который отправляет запрос, или о ресурсе, который необходимо передать. Например, Accept, User-Agent.
Общие заголовки (General Headers). Добавляются и в ответы и в запросы, не относятся непосредственно к телу сообщения. Например, Cache-Control, Connection.
Сущностные заголовки (Entity Headers), предназначены для описания тела сообщения, его модификация и тип. Например, Content-Type, Content-Encoding.
# Определение заголовков, которые будут отправлены с запросом headers = { 'User-Agent': 'Mozilla/5.0', # Идентификация типа браузера, который отправляет запрос 'Accept': 'text/html,application/xhtml+xml', # Типы контента, которые клиент может обработать 'Connection': 'keep-alive' # Указание на необходимость использования постоянного соединения } # Выполнение GET-запроса с установленными заголовками response = requests.get('http://httpbin.org/user-agent', headers=headers) print(response.text)
Основные моменты в коде:
headers – создание словаря с набором заголовков, которые буду добавлены в HTTP-запрос.
‘User-Agent’: ‘Mozilla/5.0’ — указание, под какой браузер маскировать скрипт.
‘Accept’: ‘text/html,application/xhtml+xml’ — данный заголовок указывает, какие типы данных клиент может обрабатывать.
‘Connection’: ‘keep-alive’ – данное значение указывает, что созданное соединение должно оставаться открытым для принятия последующих запросов.
response = requests.get(‘http://httpbin.org/user-agent’, headers=headers) – вызывается метод .get(), передается URL и подготовленный набор заголовков. Возвращаемый объект сохраняется в переменной response, через которую в дальнейшем можно получить необходимую информацию.
Реальный User-Agent можно посмотреть в параметрах обозревателя. К примеру, в Google Chrome для этого необходимо в адресную строку вставить команду: chrome://version/
Практика показывает, что многие популярные сайты используют различные механизмы блокировок скриптов для сканирования. Самый очевидный способ распознать его – проверить наличие заголовков. Во многих случаях добавления корректных заголовков достаточно, чтобы получить нужные данные и продолжить работу.
# Создание словаря с заголовками, которые будут использоваться для маскировки под браузер headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 'Accept-Language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7', 'Accept-Encoding': 'gzip, deflate, br' } # Выполнение GET-запроса с указанными заголовками response = requests.get('http://httpbin.org/user-agent', headers=headers) # В переменной response хранится ответ сервера, который можно дальше обработать print(response.text)
В данном примере использовались следующие заголовки:
User-Agent – идентификация приложения, при помощи которого отправляется запрос.
Accept-Encoding – позволяет явно указать методы сжатия, которые доступны для обработки клиентом.
Accept-Language – указывает на предпочтительные для клиента языки.
Примерно так выглядит стандартный User-Agent для скрипта на Python. Важно понимать, что активный парсинг различными ботами может замедлять работу сайта, нагружая аппаратные мощности. Поэтому они вынуждены постоянно работать над способами блокировки такой активности.
Какие еще меры можно предпринять
Для более глубокой маскировки часто применяется схема с периодической сменой User-Agent – их список можно предварительно сохранить в файле.
Смена IP. Аналогично предусмотрены инструменты для смены IP, например, если текущий адрес попал под блокировку. Можно использовать список прокси, сохранив информацию в файл.
Снижение частоты запросов. Очевидно, что если сервер получает большое количество запросов с небольшими и равными промежутками, это признак работы скрипта. Пользователь так работать просто не сможет. Если нет необходимости ускорять работу парсера, можно устанавливать дополнительные паузы со случайными значениями.
Решение капчи и обработка других стандартных механизмов защиты. Обычно при первых подозрениях сервис не блокирует сразу пользователя, а активирует капчу. Скриптам обходить ее достаточно сложно.
Добавление заголовков. Можно настроить другие HTTP-заголовки для имитации реального устройства.
Сессии и куки. Также позволяет сделать процесс парсинга менее подозрительным.
Анализ JavaScript. Некоторые ресурсы требуют выполнения JavaScript для доступа к основному контенту, что несколько осложняет работу программиста. Необходимо использовать дополнительные библиотеки, которые способны обеспечить интерпретацию JavaScript.
Для автоматической смены user-agent можно использовать следующий код:
import requests from random import choice url = 'http://httpbin.org/user-agent' with open('user_agent.txt') as file: lines = file.read().split('\n') for line in lines: user_agent = {'user-agent': choice(lines)} response = requests.get(url=url, headers=user_agent) print(response.text)