61

我对 cookie 如何与 Scrapy 一起工作以及您如何管理这些 cookie 感到有些困惑。

这基本上是我正在尝试做的简化版本: 在此处输入图像描述


网站的运作方式:

当您访问该网站时,您会获得一个会话 cookie。

当您进行搜索时,网站会记住您搜索的内容,因此当您执行诸如转到下一页结果之类的操作时,它会知道它正在处理的搜索。


我的脚本:

我的蜘蛛有一个 searchpage_url 的起始 url

搜索页面被请求parse()并且搜索表单响应被传递给search_generator()

search_generator()然后yield使用大量搜索请求FormRequest和搜索表单响应。

这些 FormRequest 中的每一个以及后续的子请求都需要拥有自己的会话,因此需要拥有自己的单独 cookiejar 和自己的会话 cookie。


我已经看到文档的部分讨论了阻止合并 cookie 的元选项。这实际上是什么意思?这是否意味着发出请求的蜘蛛将在其余生中拥有自己的 cookiejar?

如果 cookie 然后在每个蜘蛛级别上,那么当产生多个蜘蛛时它是如何工作的?是否可以只让第一个请求生成器产生新的蜘蛛并确保从那时起只有那个蜘蛛处理未来的请求?

我假设我必须禁用多个并发请求。否则一个蜘蛛会在同一个会话 cookie 下进行多次搜索,而未来的请求只会与最近的搜索有关?

我很困惑,任何澄清都会受到极大的欢迎!


编辑:

我刚刚想到的另一个选项是完全手动管理会话 cookie,并将其从一个请求传递到另一个请求。

我想这意味着禁用 cookie.. 然后从搜索响应中获取会话 cookie,并将其传递给每个后续请求。

这是你在这种情况下应该做的吗?

4

5 回答 5

52

三年后,我认为这正是您想要的: http ://doc.scrapy.org/en/latest/topics/downloader-middleware.html#std:reqmeta-cookiejar

只需在蜘蛛的 start_requests 方法中使用类似的东西:

for i, url in enumerate(urls):
    yield scrapy.Request("http://www.example.com", meta={'cookiejar': i},
        callback=self.parse_page)

请记住,对于后续请求,您每次都需要显式重新附加 cookiejar:

def parse_page(self, response):
    # do some processing
    return scrapy.Request("http://www.example.com/otherpage",
        meta={'cookiejar': response.meta['cookiejar']},
        callback=self.parse_other_page)
于 2014-08-26T22:33:09.907 回答
7
from scrapy.http.cookies import CookieJar
...

class Spider(BaseSpider):
    def parse(self, response):
        '''Parse category page, extract subcategories links.'''

        hxs = HtmlXPathSelector(response)
        subcategories = hxs.select(".../@href")
        for subcategorySearchLink in subcategories:
            subcategorySearchLink = urlparse.urljoin(response.url, subcategorySearchLink)
            self.log('Found subcategory link: ' + subcategorySearchLink), log.DEBUG)
            yield Request(subcategorySearchLink, callback = self.extractItemLinks,
                          meta = {'dont_merge_cookies': True})
            '''Use dont_merge_cookies to force site generate new PHPSESSID cookie.
            This is needed because the site uses sessions to remember the search parameters.'''

    def extractItemLinks(self, response):
        '''Extract item links from subcategory page and go to next page.'''
        hxs = HtmlXPathSelector(response)
        for itemLink in hxs.select(".../a/@href"):
            itemLink = urlparse.urljoin(response.url, itemLink)
            print 'Requesting item page %s' % itemLink
            yield Request(...)

        nextPageLink = self.getFirst(".../@href", hxs)
        if nextPageLink:
            nextPageLink = urlparse.urljoin(response.url, nextPageLink)
            self.log('\nGoing to next search page: ' + nextPageLink + '\n', log.DEBUG)
            cookieJar = response.meta.setdefault('cookie_jar', CookieJar())
            cookieJar.extract_cookies(response, response.request)
            request = Request(nextPageLink, callback = self.extractItemLinks,
                          meta = {'dont_merge_cookies': True, 'cookie_jar': cookieJar})
            cookieJar.add_cookie_header(request) # apply Set-Cookie ourselves
            yield request
        else:
            self.log('Whole subcategory scraped.', log.DEBUG)
于 2011-06-22T08:46:39.353 回答
1

我认为最简单的方法是使用搜索查询作为蜘蛛参数(将在构造函数中接收)运行同一蜘蛛的多个实例,以便重用 Scrapy 的 cookie 管理功能。因此,您将拥有多个蜘蛛实例,每个实例都抓取一个特定的搜索查询及其结果。但是您需要自己运行蜘蛛:

scrapy crawl myspider -a search_query=something

或者您可以使用 Scrapyd 通过 JSON API 运行所有蜘蛛。

于 2011-02-13T14:33:43.380 回答
1
def parse(self, response):
    # do something
    yield scrapy.Request(
        url= "http://new-page-to-parse.com/page/4/",
        cookies= {
            'h0':'blah',
            'taeyeon':'pretty'
        },
        callback= self.parse
    )
于 2016-02-12T07:57:58.117 回答
1

Scrapy 有一个下载器中间件CookiesMiddleware,用于支持 cookie。您只需要启用它。它模仿浏览器中 cookiejar 的工作方式。

  • 当请求通过CookiesMiddleware时,它会读取该域的 cookie 并将其设置在 header 上Cookie
  • 当响应返回时,CookiesMiddleware读取服务器在 resp header 上发送的 cookie Set-Cookie。并将其保存/合并到 mw 上的 cookiejar 中。

我已经看到文档的部分讨论了阻止合并 cookie 的元选项。这实际上是什么意思?这是否意味着发出请求的蜘蛛将在其余生中拥有自己的 cookiejar?

如果 cookie 然后在每个蜘蛛级别上,那么当产生多个蜘蛛时它是如何工作的?

每个蜘蛛都有其唯一的下载中间件。所以蜘蛛有单独的饼干罐。

通常,来自一个 Spider 的所有请求共享一个 cookiejar。但是CookiesMiddleware可以选择自定义此行为

  • Request.meta["dont_merge_cookies"] = True告诉 mw 这个 req 不是Cookie从 cookiejar 中读取的。并且不要Set-Cookie从 resp 合并到 cookiejar 中。这是一个请求级别开关。
  • CookiesMiddleware支持多个cookiejars。您必须控制在请求级别使用哪个 cookiejar。Request.meta["cookiejar"] = custom_cookiejar_name.

请提供文档和相关的源代码CookiesMiddleware

于 2021-08-04T10:59:13.720 回答