Парсинг защищённых сайтов
Недавно мне по работе появилась необходимость парсинга объявлений авито своего города. Для этого можно использовать selenium, но по тестам он достаточно медленный, при этом синхронный, что в проекте довольно нежелательно, поэтому я бы хотел использовать внутренние api сайта.
Однако никак не могу понять почему через postman запрос проходит, а через мой код нет. Вот сам запрос:
А вот мой код, этот запрос пытающийся сделать:
import requests
cookie = '' # Тут должны быть куки, но они длинные и потому я их в вопросе уберу
headers = {
"accept": "text/css,*/*;q=0.1",
"accept-encoding": "gzip, deflate, br",
"accept-language": "ru,en;q=0.9,ru-RU;q=0.8,en-US;q=0.7",
"if-modified-since": "Wed, 10 May 2023 14:32:37 GMT",
"referer": "https://www.avito.ru/",
"sec-ch-ua": "\"Google Chrome\";v=\"113\", \"Chromium\";v=\"113\", \"Not-A.Brand\";v=\"24\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "style",
"sec-fetch-mode": "no-cors",
"sec-fetch-site": "cross-site",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ]"
"(KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
"x-client-data": "CJC2yQEIorbJAQipncoBCOfaygEIlqHLAQiFoM0BCIunzQEIx6rNAQ==",
"cookie": cookie
}
link2 = "https://www.avito.ru/web/1/main/items?forceLocation=false&locationId=653040&" \
"lastStamp=1683748131&limit=30&offset=89&categoryId=4"
def get_page():
session = requests.session()
test = session.get(link2, headers=headers)
print(test.text)
get_page()
Что я делаю не так? Подскажите, пожалуйста. Заранее просто огромнейшее спасибо!
Ответы (1 шт):
Авито возвращает 403 при таком запросе. В информации пишется, что "ваш ip временно заблокирован", однако это стандартный ответ авито при неправильном запросе
Нет, это не стандартный ответ Авито при неправильном запросе…
Смотрите что он вам выдаёт:
{
"status": "too-many-requests",
"result": {
"message": "Доступ с вашего IP-адреса временно ограничен",
"link": "ru.avito://1/firewall/captcha/show"
}
}
Ключевое слово в link — это captcha, при этом браузер никакую не запрашивает. Очень похоже на то что cloudflare делает, и про такие защиты уже отвечал тут и‥ могу с уверенностью сказать, что замечательный cloudscraper здесь работает не хуже:
import cloudscraper
s = cloudscraper.create_scraper(delay=10, browser={'custom': 'ScraperBot/1.0'})
url = 'https://www.avito.ru/web/1/main/items'
params = {
'forceLocation': False,
'locationId': 653040,
'lastStamp': 1683748131,
'limit': 30,
'offset': 89,
'categoryId': 4
}
r = s.get(url, params=params)
print(r)
Вывод:
<Response [200]>
Как распознать, что защита именно та, которую можно обойти данной библиотекой? Запрос занимает значительно больше времени чем в браузере, как раз из-за проверки, которая не может увенчаться успехом. При пройденной проверке запрос отрабатывает моментально.
И ещё, пожалуйста, не делайте длинные ссылки переносимые через \, параметры можно без проблем упаковывать в параметры.
Headers для успешного выполнения не потребовались, но лучше с ними, чем без них.