Невозможно получить Set-cook ie в обратном вызове, но можно получить его в оболочке Scrapy - PullRequest
0 голосов
/ 21 июня 2020

Я пытаюсь получить значение Set-cook ie из заголовков ответа с помощью этого запроса:

def start_requests(self):
        yield scrapy.Request("https://segmentfault.com/channel/backend", method='GET', headers=self.headers, callback=self.parse, meta={'pages': self.pages})

def parse(self, response):
        print(response.headers)

Но в результатах нет ключа с именем Set-Cook ie:

{b'Date': [b'Sun, 21 Jun 2020 06:11:15 GMT'], b'Content-Type': [b'text/html; charset=UTF-8'], b'Expires': [b'Thu, 19 Nov 1981 08:52:00 GMT'], b'Cache-Control': [b'no-store, no-cache, must-revalidate'], b'Pragma': [b'no-cache'], b'X-Hit': [b'web1'], b'Strict-Transport-Security': [b'max-age=15768000; preload']}

Однако с оболочкой scrapy я получаю это из ответа:

(Tensorflow2.0) ritsuko@MacBook-Pro ~/P/a/gu> scrapy shell "https://segmentfault.com/channel/backend"
2020-06-21 13:15:26 [scrapy.utils.log] INFO: Scrapy 1.8.0 started (bot: scrapybot)
2020-06-21 13:15:26 [scrapy.utils.log] INFO: Versions: lxml 4.4.2.0, libxml2 2.9.10, cssselect 1.1.0, parsel 1.5.2, w3lib 1.21.0, Twisted 19.10.0, Python 3.7.4 (v3.7.4:e09359112e, Jul  8 2019, 14:54:52) - [Clang 6.0 (clang-600.0.57)], pyOpenSSL 19.1.0 (OpenSSL 1.1.1d  10 Sep 2019), cryptography 2.8, Platform Darwin-18.7.0-x86_64-i386-64bit
2020-06-21 13:15:26 [scrapy.crawler] INFO: Overridden settings: {'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'LOGSTATS_INTERVAL': 0}
2020-06-21 13:15:27 [scrapy.extensions.telnet] INFO: Telnet Password: 17f1172f177de3f1
2020-06-21 13:15:27 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.memusage.MemoryUsage']
2020-06-21 13:15:27 [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-06-21 13:15:27 [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-06-21 13:15:27 [scrapy.middleware] INFO: Enabled item pipelines:
[]
2020-06-21 13:15:27 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2020-06-21 13:15:27 [scrapy.core.engine] INFO: Spider opened
2020-06-21 13:15:27 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://segmentfault.com/channel/backend> (referer: None)
2020-06-21 13:15:33 [asyncio] DEBUG: Using selector: KqueueSelector
[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x104720a50>
[s]   item       {}
[s]   request    <GET https://segmentfault.com/channel/backend>
[s]   response   <200 https://segmentfault.com/channel/backend>
[s]   settings   <scrapy.settings.Settings object at 0x106e24490>
[s]   spider     <DefaultSpider 'default' at 0x107354350>
[s] Useful shortcuts:
[s]   fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s]   fetch(req)                  Fetch a scrapy.Request and update local objects 
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser
2020-06-21 13:15:33 [asyncio] DEBUG: Using selector: KqueueSelector
In [1]: response.headers.getlist("Set-Cookie")                                                                                                                                  
Out[1]: [b'PHPSESSID=web1~menj0gqqie8tkj9kgej94r2h2k; path=/']

In [2]: response.headers                                                                                                                                                                                                                                                                                                                                             
Out[2]: 
{b'Date': b'Sun, 21 Jun 2020 05:14:46 GMT',
 b'Content-Type': b'text/html; charset=UTF-8',
 b'Set-Cookie': b'PHPSESSID=web1~menj0gqqie8tkj9kgej94r2h2k; path=/',
 b'Expires': b'Thu, 19 Nov 1981 08:52:00 GMT',
 b'Cache-Control': b'no-store, no-cache, must-revalidate',
 b'Pragma': b'no-cache',
 b'X-Hit': b'web1',
 b'Strict-Transport-Security': b'max-age=15768000; preload'}

COOKIES_ENABLED по умолчанию установлено True, и я также пробовал с Postman с тем же заголовки запроса, но Set-cook ie действительно появлялся в заголовках ответа.

У кого-нибудь есть идеи?

1 Ответ

0 голосов
/ 21 июня 2020

AFAIUI, Scrapy извлекает Set-Cookie заголовки из ответа и сохраняет их в cook ie jar. Это произошло в process_response методе CookiesMiddleware. Он вызывает метод extract_cookies класса CookieJar, который делает именно это. Таким образом, вы не найдете заголовки после этого момента.

Вы можете установить COOKIES_DEBUG, чтобы заголовки регистрировались.

...