Логин пользователя scrapy не работает с FormRequest.from_response () - PullRequest
1 голос
/ 03 августа 2020

Я только что установил простой Scrapy-Spider для сканирования некоторых данных, защищенных именем пользователя. В течение нескольких часов я пытался войти с помощью Scrapy FormRequest.from_response() на следующий веб-сайт, используя локальный вход (второй): https://www.campus.uni-erlangen.de/

Как я могу видеть из вывода консоли , данные отправляются на сервер (см. прикрепленный файл журнала -> ПЕРЕНАПРАВЛЕНИЕ 302), но после этого перенаправления вход в систему не был успешным. Я предполагаю, что это как-то связано с файлами cookie, но я не смог решить эту проблему.

Также в приложении вы найдете захваченный сетевой трафик c во время обычного входа в систему.

Для testreasons я попробовал с тем же кодом войти в систему http://quotes.toscrape.com/login. Это сработало!

Scrapy-Code:

import scrapy
from scrapy.shell import inspect_response
from urllib.parse import urlparse


class QuotesSpider(scrapy.Spider):
    name = "meincampus3"
    start_urls = ['https://www.campus.uni-erlangen.de/qisserver/rds?state=user&type=0']

    def parse(self, response):
        full_url = response.xpath('//*[@id="loginform"]/@action').extract_first()
        query = urlparse(full_url).query
        login_url = "https://www.campus.uni-erlangen.de/qisserver/rds?" + query
        print("fullurl: "+full_url)
        print("query: "+query)
        print("loginurl: " + login_url)

        return scrapy.FormRequest.from_response(
            response,
            url=login_url,
            formid='loginform',
            clickdata={'type': 'submit'},
            formdata={
                'username': 'UN',
                'password': 'PASSWD',
                'submit': 'Anmelden',
            },
            callback=self.after_login,
        )


    def after_login(self, response):
        inspect_response(response, self)

Консольный вывод:

(env) johannesschilling@Johannes-MBP scrapytutorial % scrapy crawl meincampus3
2020-08-04 11:29:28 [scrapy.utils.log] INFO: Scrapy 2.2.1 started (bot: scrapytutorial)
2020-08-04 11:29:28 [scrapy.utils.log] INFO: Versions: lxml 4.5.2.0, libxml2 2.9.10, cssselect 1.1.0, parsel 1.6.0, w3lib 1.22.0, Twisted 20.3.0, Python 3.7.7 (default, Jun  4 2020, 19:29:32) - [Clang 11.0.3 (clang-1103.0.32.62)], pyOpenSSL 19.1.0 (OpenSSL 1.1.1g  21 Apr 2020), cryptography 3.0, Platform Darwin-19.5.0-x86_64-i386-64bit
2020-08-04 11:29:28 [scrapy.utils.log] DEBUG: Using reactor: twisted.internet.selectreactor.SelectReactor
2020-08-04 11:29:28 [scrapy.crawler] INFO: Overridden settings:
{'BOT_NAME': 'scrapytutorial',
 'NEWSPIDER_MODULE': 'scrapytutorial.spiders',
 'SPIDER_MODULES': ['scrapytutorial.spiders']}
2020-08-04 11:29:28 [scrapy.extensions.telnet] INFO: Telnet Password: 239396afe0083e22
2020-08-04 11:29:28 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.memusage.MemoryUsage',
 'scrapy.extensions.logstats.LogStats']
2020-08-04 11:29:28 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',
 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2020-08-04 11:29:28 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2020-08-04 11:29:28 [scrapy.middleware] INFO: Enabled item pipelines:
[]
2020-08-04 11:29:28 [scrapy.core.engine] INFO: Spider opened
2020-08-04 11:29:28 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2020-08-04 11:29:28 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2020-08-04 11:29:29 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.campus.uni-erlangen.de/qisserver/rds?state=user&type=0> (referer: None)
fullurl: /qisserver/rds;jsessionid=6EA68E318E6C51D64DEFD0EA6C33417A.cit-prod-tomcat1;xuser=6DB5F329336AE359E3568D30A10EBC75.cit-prod-tomcat1?state=user&type=1
query: state=user&type=1
loginurl: https://www.campus.uni-erlangen.de/qisserver/rds?state=user&type=1
2020-08-04 11:29:29 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (302) to <GET https://www.campus.uni-erlangen.de/qisserver/rds?state=user&type=0&category=menu.browse&breadCrumbSource=&startpage=portal.vm> from <POST https://www.campus.uni-erlangen.de/qisserver/rds?state=user&type=1>
2020-08-04 11:29:29 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.campus.uni-erlangen.de/qisserver/rds?state=user&type=0&category=menu.browse&breadCrumbSource=&startpage=portal.vm> (referer: https://www.campus.uni-erlangen.de/qisserver/rds?state=user&type=0)
[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x10a1cb5d0>
[s]   item       {}
[s]   request    <GET https://www.campus.uni-erlangen.de/qisserver/rds?state=user&type=0&category=menu.browse&breadCrumbSource=&startpage=portal.vm>
[s]   response   <200 https://www.campus.uni-erlangen.de/qisserver/rds?state=user&type=0&category=menu.browse&breadCrumbSource=&startpage=portal.vm>
[s]   settings   <scrapy.settings.Settings object at 0x10b1ed710>
[s]   spider     <QuotesSpider 'meincampus3' at 0x10b04cc50>
[s] Useful shortcuts:
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser
>>> 

Networktraffi c Общий POST-запрос

Networktraffi c Заголовок POST-запроса

Networktraffi c Данные POST-запроса

Попытка входа:

просмотр (ответ) с неправильным паролем

просмотр (ответ) с правильным паролем

POST-информация от правильного ручного входа

GET-Info от правильного ручного входа

1 Ответ

0 голосов
/ 03 августа 2020

Я не уверен, что это сработает, потому что у меня нет действительного имени пользователя или пароля, но похоже, что URL-адрес, указанный в from_response, отличается от того, который мы видим в сетевом трафике c. Я бы также указал форму (чтобы убедиться, что FormRequest ищет правильную форму) и данные о кликах (чтобы убедиться, что мы имитируем щелчок по правильной кнопке):

from urllib.parse import urlparse

full_url = response.xpath('//*[@id="loginform"]/@action').extract_first()
query = urlparse(full_url).query
login_url = "https://www.campus.uni-erlangen.de/qisserver/rds?" + query
headers = {
    'Connection': 'keep-alive',
    'Pragma': 'no-cache',
    'Cache-Control': 'no-cache',
    'Upgrade-Insecure-Requests': '1',
    'Origin': 'https://www.campus.uni-erlangen.de',
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-User': '?1',
    'Sec-Fetch-Dest': 'document',
    'Referer': 'https://www.campus.uni-erlangen.de/qisserver/rds?state=user&type=0',
    'Accept-Language': 'en-GB,en;q=0.9,nl-BE;q=0.8,nl;q=0.7,ro-RO;q=0.6,ro;q=0.5,en-US;q=0.4,fr;q=0.3,it;q=0.2',
}

return scrapy.FormRequest.from_response(
            response,
            url=login_url,
            formid='loginform',
            clickdata={'type': 'submit'},
            formdata={
                'username': 'USERNAME',
                'password': 'PASSWD',
                'submit': 'Anmelden',
            },
            callback=self.after_login,
            headers=headers
        )
...