Не удается войти на сайт с помощью запросов

#python #python-3.x #web-scraping #python-requests

#python #python-3.x #очистка веб-страниц #python-запросы

Вопрос:

Я пытаюсь войти на этот сайт с помощью модуля запросов, но я получаю 403 код состояния каждый раз, когда пытаюсь выполнить следующую попытку. Хотя я пытался имитировать способ отправки запросов с помощью инструментов мониторинга разработчиков, я не могу заставить это работать. Учетные данные (имя пользователя: simpndev@gmail.com , пароль: agb5E2?w2pQJ3z ), которые я использовал здесь, предназначены только для тестирования, поэтому вы можете свободно ими пользоваться.

Чтобы получить форму, все, что вам нужно сделать, это нажать на login кнопку, а затем на Fantasy button.

Я пытался с:

 import re
import requests

link = 'https://www.fanduel.com/contests'
url = 'https://api.fanduel.com/sessions'

payload = {"email":"simpndev@gmail.com","password":" agb5E2?w2pQJ3z","product":"DFS"}

def log_in(s):
    r = s.get(link)
    client_id = re.findall(r"clientId":"(.*?)",",r.text)[0]
    s.headers['authorization'] = f'Basic {client_id}'
    s.headers['Referer'] = 'https://www.fanduel.com/login'
    s.headers['accept'] = 'application/json'
    r = s.post(url,json=payload)
    print(r.status_code)

if __name__ == '__main__':
    with requests.Session() as s:
        s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36'
        log_in(s)
  

Я добился успеха, используя selenium, поэтому я не хочу идти этим путем.

Как я могу войти на этот сайт с помощью запросов?

Ответ №1:

В этом запросе содержится 2 потенциальных ошибки 403. 403 из bot protection в link = 'https://www.fanduel.com/contests' и 403 из запроса в / sessions/

403 от link использует некоторые расширенные функции браузеров для проверки повторных попыток входа. Это будет более сложная тема, включающая сравнение строк пользовательского агента с трафиком HTTP2, преодоление капчи с помощью ML и так далее. Мой совет — не идти по этому пути.

Вместо этого уменьшите версию строки вашего пользовательского агента и убедитесь, что вы предоставляете правильные заголовки. Вы не предоставляете правильные заголовки для первоначального запроса, и поэтому вы генерируете 403s, а затем вы попадаете в черный список ботов и пытаетесь управлять этим.

У меня работает следующее, как показано на скриншоте отладчика ниже:

 import re
import requests

link = 'https://www.fanduel.com/contests'
url = 'https://api.fanduel.com/sessions'

payload = {"email":"simpndev@gmail.com","password":" agb5E2?w2pQJ3z","product":"DFS"}

def log_in(s):
    r = s.get(link)
    client_id = re.findall(r"clientId":"(.*?)",",r.text)[0]
    s.headers['Authorization'] = f'Basic {client_id}'
    s.headers['Referer'] = 'https://www.fanduel.com/login?cc_success_url=/contests'
    s.headers['Accept'] = 'application/json'
    s.headers['Accept-Encoding'] = 'gzip, deflate, br'
    s.headers['Accept-Language'] = 'en-US,en;q=0.5'
    s.headers['Origin'] = "https://www.fanduel.com"
    r = s.post(url,json=payload)
    print(r.status_code)

if __name__ == '__main__':
    with requests.Session() as s:
        s.headers['User-Agent'] = 'Mozilla/5.0 (en-us) AppleWebKit/534.14 (KHTML, like Gecko; Google Wireless Transcoder) Chrome/9.0.597 Safari/534.14 wimb_monitor.py/1.0'
        log_in(s)
  

Обратите внимание, что я изменил ваш реферер, изменил заглавные буквы в ваших заголовочных ключах и предоставил то, что может показаться лишними заголовками. При проверке r.request.headers я увидел различия между теми, которые отправляются запросами, и, например, Firefox, поэтому я просто добавил все, что отличалось.

Также обратите внимание, что ваш токен на предъявителя и учетные данные учетной записи теперь широко распространены и могут привести к дополнительным 403 секундам, если вы все еще используете их для тестирования. Вам понадобится чистая учетная запись, поскольку многие люди могут иметь эти учетные записи сейчас.

введите описание изображения здесь

Комментарии:

1. Я использовал инструменты разработчика Chrome для сбора и использования заголовков в моем первоначальном скрипте. Я перепроверил, не использовал ли я ошибочно маленькую букву в ключах заголовка, но заметил, что я не ошибся. Ваш код работает без ошибок. У меня вопрос по этому поводу: как вы выяснили, что ключи заголовка должны использоваться печатными буквами и каким может быть точный пользовательский агент? Огромное спасибо.

2. Я выбрал user-agent случайным образом из списка старых пользовательских агентов (погуглил). Я использовал Firefox для пар ключ заголовка-> значение. Возможно, все, что было необходимо, это исправление значения Referer (обратите внимание, что я добавил фрагмент строки запроса), но я просто добавил все одновременно.

Ответ №2:

Был там, в прошлом было много проблем с использованием Selenium для очистки веб-страниц.

Одна из альтернатив, которая мне больше нравится, — это использование mitmproxy для сброса скрипта навигации в файл и воспроизведения его с помощью requests , что-то вроде этого:

 import mitmproxy.io
import requests

def main():
    sess = requests.Session()
    with open('flows', 'rb') as f: data = [row for row in mitmproxy.io.FlowReader(f).stream()]
    for d in data:
        url = d.request.url
        raw_content = d.request.raw_content
        headers = dict([(k, v,) for k, v in d.request.headers.items() if not k.startswith(':') and k.lower() != 'cookie'])
        print(url, raw_content, headers)
        if d.request.method == 'GET':
            r = sess.get(url, headers=headers, data=raw_content)
        if d.request.method == 'POST':
            r = sess.post(url, headers=headers, data=raw_content)
        print(r.status_code)
        if d.request.url == 'https://api.fanduel.com/sessions':
            break

if __name__ == '__main__':
    main()
  

Приведенный выше код (с использованием моего собственного потока, выгруженного из mitmproxy) приводит к выводам ниже:

 http://www.fanduel.com/ b'' {'Host': 'www.fanduel.com', 'Upgrade-Insecure-Requests': '1', 'Accept': 'text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Mobile/15E148 Safari/604.1', 'Accept-Language': 'en-gb', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive'}
200
https://www.fanduel.com/ b'' {'accept': 'text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Mobile/15E148 Safari/604.1', 'accept-language': 'en-gb', 'accept-encoding': 'gzip, deflate'}
200
https://www.fanduel.com/JMCVuBG8/init.js b'' {'accept': '*/*', 'accept-encoding': 'gzip, deflate, br', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Mobile/15E148 Safari/604.1', 'accept-language': 'en-gb', 'referer': 'https://www.fanduel.com/'}
200
https://www.fanduel.com/login?source=Header Login b'' {'accept': 'text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8', 'accept-encoding': 'gzip, deflate, br', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Mobile/15E148 Safari/604.1', 'accept-language': 'en-gb', 'referer': 'https://www.fanduel.com/'}
200 
https://api.fanduel.com/sessions b'{"email":"simpndev@gmail.com","password":" agb5E2?w2pQJ3z","product":"DFS"}' {'accept': 'application/json', 'origin': 'https://www.fanduel.com', 'content-type': 'application/json', 'authorization': 'Basic ZWFmNzdmMTI3ZWEwMDNkNGUyNzVhM2VkMDdkNmY1Mjc6', 'referer': 'https://www.fanduel.com/login', 'content-length': '75', 'accept-language': 'en-gb', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Mobile/15E148 Safari/604.1', 'accept-encoding': 'gzip, deflate, br'}
201
  

Все, что вам понадобится, это устройство с установленным прокси для прохождения через вашу собственную установку mitmproxy (обычно я использую свой телефон для маршрутизации запросов с помощью моего ПК и SOCKS5). Если что-то изменится в навигации по веб-сайту, все, что вам нужно будет сделать, это создать новый поток и дамп скрипта для загрузки в программу Python.

Это не решит более сложных реализаций безопасности javascript, но должно быть достаточно для простых, таких как этот веб-сайт.