Как авторизоваться на сайте через python requests
Перейти к содержимому

Как авторизоваться на сайте через python requests

  • автор:

Аутентификация с модулем requests в Python

Библиотека requests позволяет указать собственный механизм аутентификации, а так же поддерживает без дополнительной настройки механизм базовой аутентификации.

Реализации аутентификации являются подклассами AuthBase и легко поддаются определению. Библиотека requests предоставляет две общие реализации схемы аутентификации в подмодуле requests.auth : HTTPBasicAuth и HTTPDigestAuth .

Пользовательский механизм аутентификации.

Любой вызываемый объект, который передается в качестве аргумента auth методу запроса, имеет возможность изменить запрос перед его отправкой.

Представим, что у есть веб-сервис, который будет отвечать только в том случае, если заголовок X-Pizza имеет значение пользователя. Это маловероятно, ну просто представим такую схему.

from requests.auth import AuthBase class PizzaAuth(AuthBase): """Присоединяет HTTP аутентификацию к объекту запроса.""" def __init__(self, username): # здесь настроем любые данные, связанные с аутентификацией self.username = username def __call__(self, req): # изменяем и возвращаем запрос req.headers['X-Pizza'] = self.username return req 

Затем можно сделать запрос, используя созданный класс PizzaAuth() :

>>> requests.get('http://pizzabin.org/admin', auth=PizzaAuth('superken')) #

Пример базовой аутентификации.

Библиотека requests позволяет легко использовать многие формы аутентификации, включая очень распространенную базовую аутентификацию.

# псевдокод (необходимо определить используемые переменные) >>> from requests.auth import HTTPBasicAuth # указываем параметры аутентификации >>> auth = HTTPBasicAuth('fake@example.com', 'password') >>> resp = requests.post(url=url, data=body, auth=auth) >>> resp.status_code # 201 >>> content = resp.json() >>> print(content['body']) 

Расширение Requests-OAuthlib .

Расширение requests-oauthlib позволяет автоматически выполнять OAuth1 и OAuth2 аутентификацию из библиотеки requests без танцев с бубном.

Расширение будет полезно для большого числа веб-сайтов, которые используют OAuth1/2 для обеспечения быстрой аутентификации. Оно также предоставляет множество настроек, которые обрабатывают способы, которыми конкретные поставщики OAuth отличаются от стандартных спецификаций.

Для начала использования requests-oauthlib , его необходимо установить.

$ pip install requests_oauthlib

Расширение использует библиотеки Python requests и | OAuthlib |, чтобы предоставить простой в использовании интерфейс для создания клиентов OAuth1 и OAuth2 .

В приведенном ниже примере показано веб-приложение, использующее веб-фреймворк Flask , которое подключается к API Github OAuth2 . Этот пример должен быть легко перенесен на любой веб-фреймворк.

Хотя последовательность операций у большинства провайдеров остается неизменной, особенность Github заключается в том, что параметр redirect_uri является необязательным. Это означает, что может потребоваться явная передача redirect_uri объекту OAuth2Session (например, при создании настраиваемого OAuthProvider с помощью | flask-oauthlib |).

from requests_oauthlib import OAuth2Session from flask import Flask, request, redirect, session, url_for from flask.json import jsonify import os app = Flask(__name__) # Эта информация получена при регистрации нового приложения # GitHub OAuth здесь: https://github.com/settings/applications/new client_id = "" client_secret = "" authorization_base_url = 'https://github.com/login/oauth/authorize' token_url = 'https://github.com/login/oauth/access_token' @app.route("/") def demo(): """1: Авторизация пользователя. Перенаправление пользователя/владельца ресурса к поставщику OAuth (например, Github) использование URL-адреса с несколькими ключевыми параметрами OAuth. """ github = OAuth2Session(client_id) authorization_url, state = github.authorization_url(authorization_base_url) # Состояние используется для предотвращения CSRF, оставим на потом. session['oauth_state'] = state return redirect(authorization_url) # 2: Авторизация пользователя, это происходит на провайдере. @app.route("/callback", methods=["GET"]) def callback(): """ 3: Получение токена доступа. Пользователь был перенаправлен обратно от поставщика на зарегистрированный URL обратного вызова. С этим перенаправлением приходит код авторизации, включенный в URL-адрес перенаправления. Используем это, чтобы получить маркер доступа. """ github = OAuth2Session(client_id, state=session['oauth_state']) token = github.fetch_token(token_url, client_secret=client_secret, authorization_response=request.url) # На этом этапе уже можно получить защищенные ресурсы, сохраним # токен и покажем, как это делается из сохраненного токена в /profile. session['oauth_token'] = token return redirect(url_for('.profile')) @app.route("/profile", methods=["GET"]) def profile(): """Извлечение защищенного ресурса с помощью токена OAuth 2. """ github = OAuth2Session(client_id, token=session['oauth_token']) return jsonify(github.get('https://api.github.com/user').json()) if __name__ == "__main__": # Это позволяет нам использовать вызов по HTTP os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = "1" app.secret_key = os.urandom(24) app.run(debug=True) 

Обратите внимание, что Oauth2 работает через уровень SSL. Если сервер не настроен для поддержки HTTPS, то метод fetch_token вызовет ошибку oauthlib.oauth2.rfc6749.errors.InsecureTransportError . Большинство людей не устанавливают SSL на своих серверах во время тестирования, и это нормально. Можно отключить эту проверку двумя способами:

    Установив переменную окружения.

export OAUTHLIB_INSECURE_TRANSPORT=1 
# Где-то в webapp_example.py, например, # перед запуском приложения. import os os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' 

Python requests. Авторизация на сайте

Иногда при парсинге страниц нужно получить данные , которые недоступны незарегистрированным пользователям. Для этого нужно авторизоваться на сайте. И в этой статье я покажу как с помощью замечательной библиотеки requests это реализовать.

В качестве примера попробуем залогиниться на сайте hh.ru.

Python авторизация

Как видим нам нужно ввести Email или Телефонный номер в качестве ЛОГИНА и ПАРОЛЬ и нажать кнопку Войти в личный кабинет.

Установка библиотеки Requests

 pip install requests 

Указываем User-Agent

Казалось бы , нам нужно просто реализовать метод post этой библиотеки , передав все необходимые данные. Но не так просто , так как нам нужно указать правильный User-Agent и вытащить из кукис файлов значение _xsrf.

User-agent ? И что за значение _xsrf ? Что ты несешь , чувак? Наверно, такие вопросы у вас возникли читая предыдущие строки.Попробую объяснить о чем речь

Попытаемся просто сделать GET запрос на сайт hh.ru и посмотреть какой ответ он возвращает.

Python авторизация

Как мы видим сервер нам возвращает ОТВЕТ 404 , который говорит , что нет такой страницы. Но если мы выполним запрос через браузер , то все нормально.

Такая ошибка происходит из-за того , что сервер думает , что мы робот , так по умолчанию User-Agent отправляемого запроса равен python-requests/2.22.0. Чтобы сервер нам возвращал нормальный ответ , нужно указать правильный User-Agent, который эмулирует действия пользователя.

 import requests headers = < 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' >r = requests.get("https://hh.ru", headers=headers) print(r) 

Объект Session

Теперь разберемся для чего нужен _xsrf . Когда мы логинимся на сайте hh.ru , то мы просто вводим логин и пароль и все. Но при этом при POST запросе на сервер кроме введенных нами значений передается и параметр _xsrf, который нужен для защиты от CSRF-атак. Так вот значение этого параметра сервер hh.ru генерирует автоматически и хранит его в кукис файлах в браузере и чтобы получить это значение , нам нужно использовать объект Session библиотеки requests.

Объект Session позволяет сохранять определенные параметры в запросах.Он также сохраняет файлы COOKIE во всех запросах.

Здесь я привожу полный текст скрипта с подробными комментариями, который осуществляет авторизаицю на сайте hh.ru.

 import requests url = 'https://moscow.hh.ru/account/login' # Важно. По умолчанию requests отправляет вот такой # заголовок 'User-Agent': 'python-requests/2.22.0 , а это приводит к тому , что Nginx # отправляет 404 ответ. Поэтому нам нужно сообщить серверу, что запрос идет от браузера user_agent_val = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' # Создаем сессию и указываем ему наш user-agent session = requests.Session() r = session.get(url, headers = < 'User-Agent': user_agent_val >) # Указываем referer. Иногда , если не указать , то приводит к ошибкам. session.headers.update() #Хотя , мы ранее указывали наш user-agent и запрос удачно прошел и вернул # нам нужный ответ, но user-agent изменился на тот , который был # по умолчанию. И поэтому мы обновляем его. session.headers.update() # Получаем значение _xsrf из cookies _xsrf = session.cookies.get('_xsrf', domain=".hh.ru") # Осуществляем вход с помощью метода POST с указанием необходимых данных post_request = session.post(url, < 'backUrl': 'https://moscow.hh.ru/', 'username': 'yourlogin', 'password': 'yourpassword', '_xsrf':_xsrf, 'remember':'yes', >) #Вход успешно воспроизведен и мы сохраняем страницу в html файл with open("hh_success.html","w",encoding="utf-8") as f: f.write(post_request.text) 

Заключение

В этой статье реализована практическая задача , которая осуществляет авторизацию на сайте hh.ru. Эта задача прекрасна иллюстрирует то , с чем мы можем столкнуться на практике

Обновлено(1 декабря 2020 года)

Когда писалась данная статья , то капчи(CAPTCHA) не было на сайте hh.ru и авторизация происходила успешно. Для обхода капчи нужны более сложные решения. А для авторизации на страницах , где нет капчи можно использовать вышеописанный метод. Также у меня есть статья , где рассмотрена авторизация на сайте вконтакте с помощью логина и пароля , c использованием библиотеки vk_api

Авторизация на сайте и парсинг

Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нем неправильно.
Необходимо обновить браузер или попробовать использовать другой.

orlov1
Новичок

Пользователь
Июн 23, 2021 48 2 8

Добрый день всем!

Есть код на Python, который должен выполнять авторизацию на сайте и парсинг нужного элемента в аккаунте пользователя:

import requests from bs4 import BeautifulSoup HEADERS = s = requests.Session() data = url = "https://windscribe.com/login" url1 = 'https://windscribe.com/myaccount' r = s.post(url, data=data, headers=HEADERS) r1 = s.get(url1, headers=HEADERS) print(r1.status_code) soup = BeautifulSoup(r1.text, "html.parser") user = soup.find('h1', class_='account-box-h1') print(user)

Вроде все верно, но авторизация не проходит.
Помогите решить проблему.

Vershitel_sudeb
Vershitel sudeb

Команда форума
Модератор
Мар 17, 2021 910 198 43 20 Москва

1647797053693.png

Вот какой запрос делается для входа на сайт:

как видишь тут не только логин и пароль

orlov1
Новичок

Пользователь
Июн 23, 2021 48 2 8

Вот какой запрос делается для входа на сайт:
Посмотреть вложение 1711

как видишь тут не только логин и пароль

Как правильно передать эти данные ? Они ведь генерятся для каждого запроса как я понял.

Vershitel_sudeb
Vershitel sudeb

Команда форума
Модератор
Мар 17, 2021 910 198 43 20 Москва
Да, надо разбираться откуда они берутся, тут я так сходу не помогу

regnor
Модератор

Команда форума
Модератор
Июл 7, 2020 2 564 453 83
Как правильно передать эти данные ? Они ведь генерятся для каждого запроса как я понял.
csrf токены — это защита формы, так просто не подобрать.

orlov1
Новичок

Пользователь
Июн 23, 2021 48 2 8
token и time находятся в коде страницы с формой:

Пытаюсь спарсить эти данные. Не выходит.

url = "https://windscribe.com/login" r0 = s.get(url, headers=HEADERS) soup0 = BeautifulSoup(r0.text, "html.parser") data = soup0.find_all('div', class_='login-box') for dat in data: print(dat)

Значение value = » » — не выводятся.

Vershitel_sudeb
Vershitel sudeb

Команда форума
Модератор
Мар 17, 2021 910 198 43 20 Москва

import requests from bs4 import BeautifulSoup as bs headers = get_token_url = "https://res.windscribe.com/res/logintoken" login_data = login_url = "https://windscribe.com/login" account_url = "https://windscribe.com/myaccount" ses = requests.Session() tokens = ses.post(get_token_url).json() login = ses.post(login_url, data=login_data | tokens) info = ses.get(account_url, headers=headers) soup = bs(info.text, 'lxml') user = soup.find('h1', class_='account-box-h1') print(user)
orlov1
Новичок

Пользователь
Июн 23, 2021 48 2 8

У вас этот код работает ?

У меня выдает ошибку:

line 16, in login = ses.post(login_url, data=login_data | tokens) TypeError: unsupported operand type(s) for |: 'dict' and 'dict'

Я понял, что вы дозаписываете словарь login_data значениями csrf_token и csrf_data
Последнее редактирование: Мар 21, 2022

Vershitel_sudeb
Vershitel sudeb

Команда форума
Модератор
Мар 17, 2021 910 198 43 20 Москва

У вас этот код работает ?

У меня выдает ошибку:

line 16, in login = ses.post(login_url, data=login_data | tokens) TypeError: unsupported operand type(s) for |: 'dict' and 'dict'

Я понял, что вы дозаписываете словарь login_data значениями csrf_token и csrf_data
А, у тебя python 3.8, используй login_data.update(tokens)

orlov1
Новичок

Пользователь
Июн 23, 2021 48 2 8
Да, уже сам понял в чем проблема.
В итоге вот такой код:

import requests from bs4 import BeautifulSoup as bs headers = get_token_url = "https://res.windscribe.com/res/logintoken" login_data = login_url = "https://windscribe.com/login" account_url = "https://windscribe.com/myaccount" ses = requests.Session() tokens = ses.post(get_token_url).json() login = ses.post(login_url, data=login_data.update(tokens)) info = ses.get(account_url, headers=headers) soup = bs(info.text, 'lxml') user = soup.find('h1', class_='account-box-h1') print(user)
None
Vershitel_sudeb
Vershitel sudeb

Команда форума
Модератор
Мар 17, 2021 910 198 43 20 Москва
a.update(b) обновляет a, но ничего не возвращает
ты сначала обнови login_data, а потом уже подставь

orlov1
Новичок

Пользователь
Июн 23, 2021 48 2 8

Так вроде так и есть.

Если после 17 строки вставить

print(login_data)

Возвращает корректный словарь

orlov1
Новичок

Пользователь
Июн 23, 2021 48 2 8
Разобрался.
Рабочий код:

import requests from bs4 import BeautifulSoup as bs headers = get_token_url = "https://res.windscribe.com/res/logintoken" login_data = login_url = "https://windscribe.com/login" account_url = "https://windscribe.com/myaccount" ses = requests.Session() tokens = ses.post(get_token_url).json() login_data.update(tokens) login = ses.post(login_url, data=login_data) print(login_data) info = ses.get(account_url, headers=headers) soup = bs(info.text, 'lxml') user = soup.find_all('h1', class_='account-box-h1') print(user)

Как авторизоваться на сайте через requests?

5fb178ed14501523128823.png

Всем доброго времени суток!
Столкнулся с проблемой авторизации на сайте https://easypay.ua/auth/login
Мучительно пытался найти ответ среди готовых, но видимо плохо искал.Буду благодарен, даже какой-то отсылке к подобным вопросам.
Вручную ввёл данные для входа и через инструменты разработчика нашёл запрос, который формируется, вытащил оттуда параметры и заголовки, сделал пост-запрос, получил обратно json(refresh_token, access_token,ID, username и пару дат истечения времени). В скрипте делал запрос, создавая предварительно сессию для сохранения куки, чтоб дальше работать с сайтом. Но мои возможности закончились на втором шаге, куки не удавалось пробрасывать и сайт просто не принимал авторизацию, выдавая страничку с авторизацией. Очень нуждаюсь в помощи.Спасибо заранее за любую помощь
Редактировано:
Сам запрос, сформированный сайтом:

def autorithation(): session = requests.Session() base_url = 'https://api.easypay.ua/api/token' data = headers = ans = session.post(base_url, data=data, headers=headers) return ans def get_history(): auth = autorithation() base_url = 'https://easypay.ua/profile/history' responce = requests.get(base_url, cookies=auth.cookies)

p.s. 400 — лимит авторизаций. Так выдает 200

  • Вопрос задан более трёх лет назад
  • 688 просмотров

7 комментариев

Простой 7 комментариев

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *