Как выполнить успешный вход с "запросами" в Python (GET / POST) - 409 конфликт


Как правильно войти через этот сайт?

Я хочу войти в систему здесь, используя модуль requests.

Я сделал это до сих пор:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt5 import QtCore, QtGui, QtWidgets

import requests
from utils.user_agents import get_random_user_agent


class StudentsWebSession(QtCore.QThread):

    def __init__(self, url, _url=None, username=None, password=None, payload=None):
        QtCore.QThread.__init__(self)
        self.session = requests.Session()
        self.ua = get_random_user_agent('desktop')
        self.headers_get_one = {
            'host': 'studentsweb.teimes.gr',
            'user-agent': self.ua,
            'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'accept-language': 'en-US,en;q=0.5',
            'accept-encoding': 'gzip, deflate, br',
            'connection': 'keep-alive',
            'upgrade-insecure-requests': '1'
        }
        self.headers_post_one = {
            'host': 'studentsweb.teimes.gr',
            'user-agent': self.ua,
            'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'accept-language': 'en-US,en;q=0.5',
            'accept-encoding': 'gzip, deflate, br',
            'referer': 'https://studentsweb.teimes.gr/unistudent/login.asp',
            'content-type': 'application/x-www-form-urlencoded',
            'connection': 'keep-alive',
            'upgrade-insecure-requests': '1'
        }
        self.headers_get_two = {
            'host': 'studentsweb.teimes.gr',
            'user-agent': self.ua,
            'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'accept-language': 'en-US,en;q=0.5',
            'accept-encoding': 'gzip, deflate, br',
            'referer': 'https://studentsweb.teimes.gr/unistudent/login.asp',
            'connection': 'keep-alive',
            'upgrade-insecure-requests': '1'
        }
        self.url = url
        self._url = _url
        self.username = username
        self.password = password
        self.payload = payload

    def __del__(self):
        self.wait()

    def get(self):
        with self.session as s:
            if not self.payload:
                self.payload = {
                    'userName': self.username,
                    'pwd': self.password,
                    'submit1': 'Login',
                    'loginTrue': 'login'
                }

            r = s.get(self.url, headers=self.headers_get_one,
                      params={'lang': 'en-us'})
            print(r.content.decode('cp1253'))
            #print(r.url)

            r = s.post(self.url, headers=self.headers_post_one,
                       data=self.payload)
            #print(r.content.decode('cp1253'))
            #print(r.url)

            #r = s.get(self._url, headers=self.headers_get_two)
            #print(r.content.decode('cp1253'))
            #print(r.url)

    def run(self):
        self.get()

Я инициализирую его следующим образом:

stweb = StudentsWebSession(db.get('studentsweb', {}).get('url'),
                           db.get('studentsweb', {}).get('url_after'),
                           self.extract_username_from_email(),
                           self.form_password.text())
stweb.start()

Где db - словарь, содержащий все необходимые информация.

И в результате я получаю HTML-документ с нижеприведенным заголовком (409 http-код)

 <title>409 Conflict</title>

Я думаю, что вы должны выполнить простой GET-запрос для хранения файлов cookie, а затем выполнить POST-запрос со всей необходимой грузоподъемности, заголовки и куки. А затем выполните запрос GET, чтобы получить желаемый результат.

Вот демонстрация вышеуказанных запросов:

Первая Часть

вторая часть

Я предпочитаю не использовать selenium, безголовые браузеры, а также библиотеки без потоков

Если вам нужна дополнительная информация, пожалуйста, не стесняйтесь спрашивать их.

1 2

1 ответ:

Как вы инициализируете StudentsWebSession и вызываете .get()? Предполагая, что self.payload является None и использует self.payload, Как определено в if из .get, то:

  1. 'submit1' должно быть 'Είσοδος', а не '%C5%DF%F3%EF%E4%EF%F2'. Но начиная с ' %C5...- он уже закодирован в форме, и вы хотите отправить его вместе с данными формы, чтобы предотвратить запросы.сообщение из формы-кодирование его снова, отправить полезную нагрузку в виде строки :

    Иногда может потребоваться отправить данные, не закодированные в форме. Если ты передайте в строке вместо диктанта, что данные будут отправлены непосредственно.

    Например, GitHub API v3 принимает JSON-кодированные данные POST / PATCH:

    >>> import json
    
    >>> url = 'https://api.github.com/some/endpoint'
    >>> payload = {'some': 'data'}
    
    >>> r = requests.post(url, data=json.dumps(payload))
    
  2. Не указывайте 'content-length' в headers_post_one.

  3. Когда вы делаете with requests.Session() as s:, сеанс теряется после завершения входа в систему. Поставьте его как with ... as self.session: и используйте self.session в будущих запросах.

  4. Случайное печенье, по-видимому, устанавливается, когда сообщение сделано. Он генерируется с помощью js на форме отправить. Вам нужно будет посмотреть на него, воссоздать файл cookie и отправить его вместе с запросом post. Кроме того, это не печенье rcva_, которое вы получаете в форме GET. Совпадают только первые 64 символа:

    Set-Cookie:rcva%5F=FCDB7353DAFB81C0DBDF61BD76CBBB0B4B6D6E39BC7381BEDB8A79416CBE4E9E16B9A45ABBE6175E103D0CCBBB848AF2C4000C03DDB27444CAFFBFAA7D6D6731A538DC737CE33D5A2B443E4CEF01911D08512B74B2C7062854F0857937DB92793E1FAE8518917CAD3EC03997942C7DB3FEBDD27840ECFF697EFDA93CC6CCF80A83F3A8487917131301BF32EF1B9E36CF; путь= /

    Против того, который посылается...

    Cookie: ASPSESSIONIDCWCQTDDT=CINNLLKKBNLNBKMPOMCPPKCFH; rcva%5F=FCDB7353DAFB81C0DBDF61BD76CBBB0B4B6D6E39BC7381BEDB8A79416CBE4E9EEF49F13C3FD75EBFCE526F8984772FCB4A39EE0A3563DCAFD81050CAE03092E7B0AF2A5ABB6EBE0CADF06AB9F405A1AABBC521DEF74668744D66327E2F0C6CEB17EC3757B623A057444FF457A13D97DC7438CA446840E71C358E5D1F942566602B3E31061989C8DC5A7F1F846A0680BD

  5. Кроме того, отправленные данные формы также содержат часть этого файла cookie со случайным именем, и только первые 32 символа совпадают:

    C4134bbd3f648974b8ecdc237b5ebe2fd:FCDB7353DAFB81C0DBDF61BD76CBBB0BD085AD5A217BAD80C33CC6A27FDAD06DC7E81968BC5C18767860BB38E4285D9A9E02BEE0FDFF9C7B133FAC5FE6BFAC04ED88B3038686B94083AB20C44C9CB94CA067CC376892B9F9E91514A73C659E5BD05BF72B2DC8BCD5AD399D191CC58818

  6. Не делайте self.cookies = r.cookies , так как запросы будут управлять файлами cookie в самой сессии (путем повторной отправки полученных файлов cookie). Вам также не нужно явно предоставлять его, если вы не хотите добавить отдельный файл cookie, и должны быть только эти элементы (ранее полученные файлы cookie будут отправлены в любом случае).

    Примечание: вам нужно будет выяснить, как js устанавливает cookies, когда форма будет отправлена. А затем воссоздать его в Python или...используйте selenium / или другие безголовые браузеры - что, как вы сказали, вы предпочитаете не делать.

  7. 'lang': 'en-us' в форме данные могут не иметь желаемого эффекта и могут вызвать ошибки. Чтобы установить это так, как это делает сайт, установите параметры в страница в каждом запросе: r.get(... params={'lang': 'en-us'} ...). И когда вы это сделаете, 'submit1' должно быть 'Login', для #1 выше.

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