Parsing / Сбор информации

Парсинг данных быстро и эффективно

Время прочтения: 3 мин.

Как собрать информацию с сайта? Самое первое, что приходит на ум, это использование библиотеки Selenium для прохода по сайту и нахождению нужной информации. Но, поскольку Selenium это просто автоматизированный браузер – он довольно ресурсозатратен и не очень быстр. Когда вам нужно достать, скажем тысяча записей о чём-либо, вы можете закрыть глаза на данные недостатки. Но что если вам нужно собрать тысячи, сотни тысяч или даже миллионы записей? Лучшее решение – использование запросов, хотя и с ними не всё так просто, как может показаться на первый взгляд. Предположим, вы отследили куда идет запрос, и попытались отправить его, но, если сайт имеет приличную защиту, с наибольшей вероятностью ответом на ваш запрос будет ‘403 Forbidden’. Сегодня мы и рассмотрим, как мы можем формировать запросы, дабы получать заветные данные.

Помогать нам будет библиотека requests_html:

from requests_html import HTMLSession

Отличие этой библиотеки от библиотеки requests, в том, что она поддерживает работу JavaScript (на многих сайтах исполняется JavaScript, который запрашивает от клиента базовую информацию о его браузере, соответственно обычный request такую информацию не отдаст и наш запрос будет заблокирован), а также умеет получать и хранить cookie (обычный requests не собирает cookie, опять же, многие сайты любят проверять у клиента наличие cookie файлов и если таковые у клиента отсутствуют, то он блокирует запрос от него).

Создаем сессию и отправляем запрос:

Session = HTMLSession()
r = session.get(‘https://www.name.ru/’)

В некоторых случаях одного использования этой библиотеки может хватить для успешного получения ответа от сервера. Но, в моём кейсе этого не хватило, поэтому я принялся дальше ‘очеловечивать’ свой запрос.

Для Google Chrome: нужно открыть консоль разработчика, далее вкладка Network, там вы должны найти свой запрос и посмотреть Request Headers. Далее, копируем эти самые Request Headers:

Headers = {
	‘method’: ‘GET’,
	‘authority’: ‘***.ru’,
	‘scheme’: ‘https’,
	‘path’: ‘/backend/persons/{id}/publications?limit=50%offset=0&searchPerson***’,
	‘sec-ch-ua’: ‘”Google Chrome”;v=”89”, “Chromium”;v=”89”, “;Not A Brand”; v=”99”’,
	‘accept’: ‘application/json, text/plain, */*’,
	‘sec-ch-ua-mobile’: ‘?0’,
	‘user-agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 …
	‘sec-fetch-site’: ‘same-origin’,
	‘sec-fetch-mode’: ‘cors’,
	‘sec-fetch-dest’: ‘empty’,
	‘referer’: ‘https://***.ru/person/{id}’,
	‘accept-encoding’: ‘gzip, deflate, br’,
	‘dnt’: ‘1’
}

Прикрепляем headers:

session = HTMLSession()
r = session.get(‘https://www. name.ru/’, headers = headers)

Ждём ответа от сервера, данные получены. Можем парсить их с помощью beautifulsoup4.

Так же, чтобы сервер нас не банил, нужно выдерживать задержку между запросами, сделать это можно например через time.sleep(x), задержка может быть индивидуальна для каждого сайта, но обычно 3-4 секунды это оптимальное значение.

Но что, если мы хотим получить данные быстрее? На выручку приходят прокси. Не представляет большого труда найти в интернете пул прокси, в крайнем случае купить их. Каждый раз, мы можем менять прокси для запроса, таким образом, понижая задержку для запроса и увеличивая скорость выгрузки данных. Напишем свитчер прокси для каждого запроса.

from itertools import cycle
list_proxy = [‘socks5://Username:Password@IP1:20000’,
		‘socks5://Username:Password@IP2:20000’,
		‘socks5://Username:Password@IP3:20000’,
		‘socks5://Username:Password@IP4:20000’,
		‘socks5://Username:Password@IP5:20000’]
proxy_cycle = cycle(list_proxy)
proxy = next(proxy_cycle)

for i in range(1, 100000):
	proxy = next(proxy_cycle)
	proxies = {
		“http”: proxy,
		“https”:proxy
	}
	session = HTMLSession()
	r = session.get(‘https://www. name.ru/’, headers = headers, proxies = proxies)
	time.sleep(1)

Внимание! Не убирайте задержку полностью, оставляйте задержку равной хотя бы 1-2 секундам, в противном случае, ваши действия могут быть расценены как DDoS-атака. DDoS-атаки запрещены законом и могут привести даже к уголовной ответственности.

Итак, мы научились добывать данные с сайтов быстро и эффективно, при помощи библиотеки requests.html, изучению запросов и прокси. Теперь можно использовать запросы, а не Selenium браузер.

Советуем почитать