Сайты, использующие AJAX, не отдают данные напрямую при загрузке страницы. Контент подгружается асинхронно через JavaScript после первичной отрисовки DOM. Из-за этого стандартные методы парсинга, например через requests + BeautifulSoup, не дают нужного результата: HTML-код, полученный от сервера, часто оказывается пустым или урезанным.
Чтобы извлечь данные с таких сайтов, нужно определить, какие именно AJAX-запросы выполняет страница. Это можно сделать через инструменты разработчика в браузере (вкладка Network → XHR или Fetch). Важно найти URL, на который отправляется запрос, и параметры, которые передаются в теле или через строку запроса.
После обнаружения нужного запроса его можно воспроизвести вручную с помощью библиотеки requests или httpx. Часто потребуется передать заголовки (например, User-Agent, Referer, X-Requested-With) и cookies, чтобы сервер принял запрос как «настоящий». Использовать Session() удобно, если нужно сохранить авторизацию или передать несколько последовательных запросов.
Если запрос требует токен или динамический параметр, который формируется JavaScript’ом, его можно получить через рендеринг страницы в браузере с помощью Selenium или Playwright. После загрузки страницы можно считать значение из DOM или из cookies и подставить его в ручной запрос.
Альтернативный способ – использовать mitmproxy или browsermob-proxy для анализа реального трафика между браузером и сервером. Это позволяет точно воспроизвести цепочку запросов и увидеть заголовки, параметры и JSON-ответы, даже если они динамически меняются.
Как определить, использует ли сайт ajax-запросы
Откройте сайт в браузере Google Chrome. Нажмите F12, перейдите на вкладку Network и обновите страницу. Следите за типами запросов: AJAX-запросы чаще всего относятся к типу XHR или fetch.
Если при переходе по страницам URL в адресной строке остаётся прежним, а контент меняется, это признак подгрузки данных через JavaScript. В таких случаях изменения происходят без полной перезагрузки страницы, что указывает на использование AJAX.
Отслеживайте, какие файлы загружаются после взаимодействия с элементами интерфейса (например, кнопками или фильтрами). Если появляются новые XHR-запросы, можно утверждать, что данные подгружаются динамически.
Дополнительно проверьте содержимое запросов. Откройте конкретный XHR-запрос и изучите вкладки Headers и Response. Если в ответе возвращается JSON или фрагмент HTML, это подтверждает работу AJAX.
Для автоматизации можно использовать библиотеку Selenium, чтобы имитировать действия пользователя и наблюдать за запросами через прокси-сервер, например, BrowserMobProxy.
Как найти URL-адрес ajax-запроса через инструменты разработчика
Откройте нужную страницу в браузере Google Chrome. Нажмите F12 или щёлкните правой кнопкой мыши и выберите Просмотр кода, затем перейдите на вкладку Network.
Перед обновлением страницы установите фильтр XHR, чтобы отобразить только ajax-запросы. Это поможет исключить лишние ресурсы (изображения, скрипты, стили).
Обновите страницу или выполните действие, инициирующее загрузку данных (например, прокрутка, клик по кнопке, изменение фильтра). В разделе XHR появятся запросы – обратите внимание на их имена и статус (обычно 200).
Выберите один из запросов и откройте вкладку Headers. В поле Request URL указан полный путь к ресурсу, включая параметры GET-запроса. При необходимости скопируйте его для последующего использования в Python.
Если данные отправляются методом POST, перейдите на вкладку Payload – там отображается тело запроса. Эти данные часто необходимо передавать через параметр data
в библиотеке requests
.
Проверьте вкладку Preview или Response, чтобы убедиться, что ответ сервера содержит нужные данные (обычно это JSON или HTML-фрагмент).
Если запрос инициируется скриптом динамически, воспользуйтесь вкладкой Initiator, чтобы отследить, какой файл вызывает ajax-запрос и можно ли извлечь дополнительные параметры из JavaScript-кода.
Как повторить ajax-запрос с помощью библиотеки requests
Для начала необходимо открыть инструменты разработчика (F12) в браузере, перейти на вкладку «Сеть» (Network) и отфильтровать запросы по типу XHR. Найти нужный запрос, скопировать его URL, метод (GET или POST), заголовки и тело запроса (если оно есть).
Пример повтора POST-запроса с передачей данных в формате JSON:
import requests
url = "https://example.com/api/data"
headers = {
"User-Agent": "Mozilla/5.0",
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest",
"Referer": "https://example.com/"
}
payload = {
"param1": "value1",
"param2": "value2"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
Если данные передаются в форме (application/x-www-form-urlencoded), параметр json=
нужно заменить на data=
:
response = requests.post(url, data=payload, headers=headers)
При использовании метода GET, параметры можно передать через аргумент params=
:
params = {"search": "keyword", "page": "2"}
response = requests.get(url, params=params, headers=headers)
Некоторые сайты проверяют наличие cookies и токенов (например, CSRF). Их нужно передавать вручную или сохранить сессией:
session = requests.Session()
session.headers.update(headers)
session.get("https://example.com/") # инициализация, возможно получение токена
response = session.post(url, json=payload)
Если в запросе используется токен, найдите его в заголовках или теле исходного запроса и передайте в headers или data.
Не используйте прокси и заголовки «наугад» – это может привести к блокировке. Повторяйте структуру оригинального запроса точно, включая порядок параметров, если сайт чувствителен к нему.
Как обработать параметры и заголовки ajax-запроса
Для корректного воспроизведения ajax-запроса в Python необходимо точно определить его параметры и заголовки. Это делается через инструменты разработчика браузера (обычно вкладка «Network»). Найдите запрос с типом XHR или fetch и изучите следующие данные:
1. URL-адрес. Он может быть относительным – в этом случае нужно вручную подставить домен.
2. Метод запроса (GET или POST). Метод влияет на способ передачи параметров: для GET они находятся в URL, для POST – в теле запроса.
3. Заголовки запроса. Их важно скопировать полностью, особенно:
Accept
– формат ожидаемого ответа (обычноapplication/json
);Content-Type
– особенно важно для POST-запросов (application/json
илиapplication/x-www-form-urlencoded
);X-Requested-With
– часто требуется значениеXMLHttpRequest
;Referer
– может быть обязательным, особенно если сервер проверяет источник запроса;Cookie
– если сайт требует авторизации или сохраняет состояние сессии.
Пример воспроизведения запроса с помощью библиотеки requests
:
import requests
url = "https://example.com/api/data"
headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest",
"Referer": "https://example.com/page",
"Cookie": "sessionid=abc123"
}
payload = {
"param1": "value1",
"param2": "value2"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
Если параметры передаются в URL, используйте params=
вместо json=
. Для application/x-www-form-urlencoded
– data=
вместо json=
. Следите за точным соответствием формата тела запроса и заголовков – это критично для корректного ответа от сервера.
Как распарсить JSON-ответ от ajax-запроса
Если сайт использует ajax-запросы, данные чаще всего возвращаются в формате JSON. Для их обработки нужен модуль requests
и стандартная библиотека json
.
- Выполните запрос к ajax-эндпоинту. Пример:
import requests
url = 'https://example.com/api/data'
headers = {
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0'
}
response = requests.get(url, headers=headers)
- Проверьте статус ответа и распарсьте JSON:
if response.status_code == 200:
data = response.json()
else:
raise Exception(f'Ошибка запроса: {response.status_code}')
- Работайте с полученными данными. Пример структуры JSON:
{
"items": [
{"id": 1, "name": "Товар 1", "price": 100},
{"id": 2, "name": "Товар 2", "price": 200}
]
}
Для извлечения нужной информации:
for item in data.get('items', []):
print(item['name'], item['price'])
- Используйте
get()
, чтобы избежать ошибок при отсутствии ключей. - Проверьте, не вложен ли нужный список глубже – изучите структуру JSON через
print(response.text)
илиjson.dumps(data, indent=2, ensure_ascii=False)
. - Если сервер требует параметры в POST-запросе – передавайте их через
data
илиjson
аргумент.
Если JSON приходит в виде строки в одном из полей HTML-страницы, используйте регулярные выражения или BeautifulSoup
для извлечения, затем – json.loads()
для разбора.
Как обойти защиту от скрапинга при работе с ajax
Большинство современных сайтов, использующих AJAX, защищаются с помощью заголовков, cookies, токенов и rate-limit ограничений. Первый шаг – изучить сетевые запросы в инструментах разработчика браузера. Ищите XHR-запросы, определяйте точный URL, параметры и заголовки.
Для обхода защиты необходимо передавать те же заголовки, что и браузер. Минимальный набор: User-Agent
, Referer
, Accept
, X-Requested-With: XMLHttpRequest
. Используйте модуль requests
с параметром headers
, копируя данные из вкладки Network.
Если сервер проверяет наличие cookies или session-токена, получите их предварительным запросом к главной странице. Используйте requests.Session()
для сохранения состояния между запросами. Некоторые сайты внедряют токены в тело HTML или JavaScript – парсите страницу с помощью BeautifulSoup
или re
, извлекайте значения и вставляйте в параметры AJAX-запроса.
Если защита включает CSRF-токены, они часто находятся в meta-тегах или hidden input. Извлекайте и передавайте их через заголовки, например: X-CSRF-Token
.
Для имитации поведения пользователя применяйте случайные задержки между запросами и чередуйте заголовки. Используйте библиотеки fake_useragent
и time.sleep()
с random.uniform()
.
При наличии защиты на основе JavaScript (например, Cloudflare или бот-чекеры) используйте Selenium с отключенным headless-режимом или Playwright. Это позволяет обойти проверки на наличие реального браузера. Убедитесь, что заголовки браузера не отличаются от стандартных, иначе сайт может заблокировать запрос.
Если сервер отслеживает частоту запросов, применяйте прокси. Меняйте IP каждые 3–5 запросов. Используйте ротацию через списки прокси или сервисы с API. Для надежности проверяйте доступность каждого прокси перед отправкой.
Сайты могут внедрять динамические параметры, генерируемые JavaScript. В таких случаях анализируйте JS-код и воспроизводите алгоритм на Python или исполняйте его через js2py
или Node.js.