Работа с куками и заголовками на примере соглашения с правилами сайта auto.ru

Работа с куками и заголовками на примере соглашения с правилами сайта auto.ru

Не всегда выходит получить код страницы простым запросом. Иногда на сайте присутствуют некоторые ограничения, не позволяющие это сделать. Часть из них можно обойти, подставив User-Agent, другие решаются подстановкой необходимых куки и заголовков. Разберем на примере auto.ru, как работать с такими сайтами.

Первый способ (быстрый)

Для начала попробуем сделать обычный запрос, допустим, через парсер Net::HTTP Net::HTTP, и посмотрим, что придет нам в ответ. Для этих целей будет использовать Тестовый парсинг в режиме дебага. Так будет удобно видеть все, что происходит от запроса к ответу, в том числе заголовки и куки. Отправим запрос на http://auto.ru.

Fotografii_2020-08-25_12.03.36.png


Ответ пришел с кодом 200 ОК. Видим, что вес ответа составляет 5553 байта. Раскрываем код страницы через See full data или листаем чуть ниже и смотрим, что нам пришло.

Fotografii_2020-08-25_12.05.12.png


Видим, что нужного нам контента нет. Чтобы продолжить работу, нужно согласиться с правилами сайта. Об этом нам подсказывает текст, выделенный красным. Смотрим дальше. Разработчики оставили нам подсказку, она выделена синим. Понимаем, что необходимо вместе с запросом передавать какие-то куки, но где их взять? Снова обратимся к дебагу и посмотрим данные об ответе, который пришел.

Fotografii_2020-08-25_12.06.34.png


Находим заголовки и видим, что среди них есть set-cookie. Это то, что нам нужно. Теперь надо создать простейший JavaScript-парсер, который первым запросом будет получать эти куки и подставлять их во все последующие запросы.

Fotografii_2020-08-25_12.07.40.png


Для удобства, создадим отдельный метод *getCookie(), в котором будет происходить вся работа с их получением. Делаем запрос на http://auto.ru без каких-либо дополнительных заголовков. Если запрос удачный, возвращаем response.headers[‘set-cookie’], который мы видели в Тестовом парсинге. Далее, в методе *parse() обращаемся к методу getCookie() и помещаем наши куки в константу cookie. Пробуем отправить второй запрос, указав в headers наши cookie и смотрим в дебаге, какой теперь будет ответ.

Fotografii_2020-08-25_12.09.35.png


Видим, что ответ не изменился. Значит чего-то не хватает. Смотрим дальше код страницы, пытаемся понять, что мы могли упустить.

Fotografii_2020-08-25_12.10.56.png


Обнаруживаем вот такую строчку, которую мы пропустили в первый раз. Попробуем подставить в наши куки «;autoru_gdpr=1;path=/;max-age=31536000;secure;domain=auto.ru».

Fotografii_2020-08-25_12.11.55.png


Вот так. Снова делаем запрос и смотрим, что получилось.

Fotografii_2020-08-25_12.12.48.png


Размер ответа стал значительно больше. Если раскрыть код, станет ясно, что все прошло успешно. Таким образом, требовалось лишь понять, каких заголовков не хватает запросу, чтобы auto.ru его пропустил и отдал нам нужные данные. Теперь мы можем передавать cookie в объект set и использовать их между запросами, единожды получив. Если в какой-то момент заголовки (куки) устареют, можно попытаться идентифицировать это по характерному ответу и получить заново, т.к. для этого будет достаточно обратиться к методу getCookie(), который мы вынесли отдельно.

Второй способ (простой, но ресурсоемкий)

Также существует альтернативный и в какой-то мере более простой вариант получения заголовков и куки через модуль puppeteer. Он может быть уместен в случаях, когда заголовков слишком много и невозможно понять, откуда они приходят. Такое довольно часто происходит с CSRF-токеном, когда он скрыт в скриптах, подгружаемых страницей динамически. Рассмотрим этот способ на примере.

Перед началом необходимо установить puppeteer в директории /aparser/files/ командой npm I puppeteer. Также необходимо создать файл config.txt с содержимым «allow_dangerous_node_modules: 1» в директории /aparser/config/, чтобы puppeteer корректно работал.

Теперь подключим puppeteer внутри нашего парсера. И сразу объявим переменную browser.

AutoRu-Example.js_%E2%80%94_C__Users_Admin_Desktop_aparser_files_%E2%80%94_Atom_2020-08-25_12.18.59.png


Переменную browser мы объявили вне класса парсера для того, чтобы можно было «аварийно» завершить его работу в методе destroy() в случае, когда по какой-то причине она не была завершена в ходе работы парсера, иначе процессы chrome.exe (chromium) будут висеть в памяти даже после окончания парсинга и нагружать компьютер.

Сразу напишем метод destroy().

AutoRu-Example.js_%E2%80%94_C__Users_Admin_Desktop_aparser_files_%E2%80%94_Atom_2020-08-25_12.20.22.png


Не забываем, что puppeteer – асинхронный модуль, значит перед его методами следует ставить await, а перед функцией\методом, в котором происходит работа с ним, нужно писать async.

Данный метод вызывается при завершении работы парсера и в случае, если переменная browser не пуста, он завершает работу (закрывает) браузер, который в ней объявлен.

Объявим внутри класса новую асинхронную функцию – getCookieByPuppeteer().

AutoRu-Example.js_%E2%80%94_C__Users_Admin_Desktop_aparser_files_%E2%80%94_Atom_2020-08-25_12.21.24.png


На вход подаем set, чтобы вытащить из него наш запрос (http://auto.ru).

Теперь по порядку. Сначала запускаем браузер с помощью метода puppeteer.launch() и помещаем его в browser. Передаем в качестве аргумента объект с параметром headless равным false. Этот параметр указывает на то, чтобы браузер запустился вместе с интерфейсом. Удобно использовать при отладке. Значение true соответственно скроет интерфейс.

Далее создаем новую страницу (browser.newPage()) и помещаем ее в константу page. Метод page.goto(url) позволяет перейти по заданной ссылке. Передаем туда set.query. Т.к. необходимо дождаться загрузки страницы, используем page.waitForSelector(selector). Где selector – указываем класс кнопки, на которую нужно нажать, чтобы согласиться с правилами. Следующим действием нажимает на эту кнопку по тому же селектору методом page.click(selector). Затем дожидаемся полной загрузки страницы (page.waitForNavigation()). После того, как страница была загружена, вытаскиваем куки методом page.cookies() и помещаем их в переменную cookie. Закрываем браузер и возвращаем cookie.

AutoRu-Example.js_%E2%80%94_C__Users_Admin_Desktop_aparser_files_%E2%80%94_Atom_2020-08-25_12.24.20.png


Далее немного изменим метод *parse(). Во-первых, добавим async перед названием метода. Во-вторых, объявим переменную cookie, как и прежде, но вместо yield* перед this.getCookieByPuppeteer() пишем await, т. к. это уже не генератор, а асинхронная функция. Больше ничего менять не нужно. Пробуем запустить тестовый парсинг.

Fotografii_2020-08-25_12.25.34.png


Можем наблюдать, как puppeteer запускает браузер, нажимает на кнопку и переходит на главную страницу. Затем браузер закрывается и куки передаются в парсер.

Смотрим, прошел ли запрос успешно.

Rabota_s_kukami_i_zagolovkami_na_primere_soglasheniya_s_pravilami_saita.odt_-_LibreOffice_Writer_2020-08-25_12.27.04.png


Видим, что все отлично.

Мы разобрали два способа работы с куки и заголовками: простой и чуть сложнее. Оба имеют право на жизнь, но рекомендуется все же использовать просто запросы, т. к. они быстрее и менее подвержены ошибкам.
  • Like
Реакции: Carbonara
Автор
Support Vlad
Просмотры
25
Первый выпуск
Обновление

Рейтинги

5,00 звёзд Оценок: 1

Ещё ресурсы от Support Vlad

Назад
Верх