【问题标题】:Access session cookie in scrapy spiders在scrapy spiders中访问会话cookie
【发布时间】:2012-02-01 06:16:12
【问题描述】:

我正在尝试访问蜘蛛中的会话 cookie。我首先使用蜘蛛登录社交网络:

    def parse(self, response):

        return [FormRequest.from_response(response,
                formname='login_form',
                formdata={'email': '...', 'pass':'...'},
                callback=self.after_login)]

after_login,我想访问会话cookie,以便将它们传递给另一个模块(此处为selenium)以进一步处理具有身份验证会话的页面。

我想要这样的东西:

     def after_login(self, response):

        # process response
        .....

        # access the cookies of that session to access another URL in the
        # same domain with the autehnticated session.
        # Something like:
        session_cookies = XXX.get_session_cookies()
        data = another_function(url,cookies)

很遗憾,response.cookies 不返回会话 cookie。

如何获取会话 cookie?我正在查看 cookie 中间件:scrapy.contrib.downloadermiddleware.cookiesscrapy.http.cookies 但似乎没有任何直接的方式来访问会话饼干。

这里有一些关于我原来的问题的更多细节:

不幸的是,我使用了你的想法,但我没有看到 cookie,尽管我确信它们存在,因为 scrapy.contrib.downloadermiddleware.cookies 中间件确实打印出了 cookie!这些正是我想要抓取的 cookie。

这就是我正在做的事情:

after_login(self,response) 方法在正确认证后接收响应变量,然后我使用会话数据访问 URL:

  def after_login(self, response):

        # testing to see if I can get the session cookies
        cookieJar = response.meta.setdefault('cookie_jar', CookieJar())
        cookieJar.extract_cookies(response, response.request)
        cookies_test = cookieJar._cookies
        print "cookies - test:",cookies_test

        # URL access with authenticated session
        url = "http://site.org/?id=XXXX"     
        request = Request(url=url,callback=self.get_pict)   
        return [request] 

正如下面的输出所示,确实有 cookie,但我无法使用 cookieJar 捕获它们:

cookies - test: {}
2012-01-02 22:44:39-0800 [myspider] DEBUG: Sending cookies to: <GET http://www.facebook.com/profile.php?id=529907453>
    Cookie: xxx=3..........; yyy=34.............; zzz=.................; uuu=44..........

所以我想得到一个字典,其中包含键 xxx、yyy 等以及相应的值。

谢谢:)

【问题讨论】:

  • 我是否理解正确,您想在 facebook 上进行身份验证,但要从在 facebook 上进行身份验证的不同域中抓取数据?

标签: session cookies session-cookies scrapy


【解决方案1】:

截至 2021 年(Scrapy 2.5.1),这仍然不是特别简单。但是您可以通过self.crawler.engine.downloader 从蜘蛛内部访问下载器中间件(如 CookiesMiddleware):

def after_login(self, response):
    downloader_middlewares = self.crawler.engine.downloader.middleware.middlewares
    cookies_mw = next(iter(mw for mw in downloader_middlewares if isinstance(mw, CookiesMiddleware)))
    jar = cookies_mw.jars[response.meta.get('cookiejar')].jar

    cookies_list = [vars(cookie) for domain in jar._cookies.values() for path in domain.values() for cookie in path.values()]
    # or
    cookies_dict = {cookie.name: cookie.value for domain in jar._cookies.values() for path in domain.values() for cookie in path.values()}

    ...

以上两种输出格式都可以使用cookies参数传递给其他请求。

【讨论】:

    【解决方案2】:

    这对我有用

    response.request.headers.get('Cookie')
    

    它似乎返回了中间件在请求、会话或其他方式中引入的所有 cookie。

    【讨论】:

      【解决方案3】:

      一个典型的例子是有一个登录服务器,它在成功登录后提供一个新的会话 ID。这个新的会话 ID 应该与另一个请求一起使用。

      这是从源代码中提取的似乎对我有用的代码。

      print 'cookie from login', response.headers.getlist('Set-Cookie')[0].split(";")[0].split("=")[1]
      

      代码:

      def check_logged(self, response):
      tmpCookie = response.headers.getlist('Set-Cookie')[0].split(";")[0].split("=")[1]
      print 'cookie from login', response.headers.getlist('Set-Cookie')[0].split(";")[0].split("=")[1]
      cookieHolder=dict(SESSION_ID=tmpCookie)
      
      #print response.body
      if "my name" in response.body:
          yield Request(url="<<new url for another server>>",   
              cookies=cookieHolder,
              callback=self."<<another function here>>")
      else:
          print "login failed"
              return 
      

      【讨论】:

        【解决方案4】:

        也许这有点矫枉过正,但我​​不知道你将如何使用这些 cookie,所以它可能很有用(摘自真实代码 - 根据你的情况进行调整):

        from scrapy.http.cookies import CookieJar
        
        class MySpider(BaseSpider):
        
            def parse(self, response):
        
                cookieJar = response.meta.setdefault('cookie_jar', CookieJar())
                cookieJar.extract_cookies(response, response.request)
                request = Request(nextPageLink, callback = self.parse2,
                              meta = {'dont_merge_cookies': True, 'cookie_jar': cookieJar})
                cookieJar.add_cookie_header(request) # apply Set-Cookie ourselves
        

        CookieJar 有一些有用的方法。

        如果您仍然看不到 cookie - 也许它们不存在?


        更新

        CookiesMiddleware代码:

        class CookiesMiddleware(object):
            def _debug_cookie(self, request, spider):
                if self.debug:
                    cl = request.headers.getlist('Cookie')
                    if cl:
                        msg = "Sending cookies to: %s" % request + os.linesep
                        msg += os.linesep.join("Cookie: %s" % c for c in cl)
                        log.msg(msg, spider=spider, level=log.DEBUG)
        

        那么,试试request.headers.getlist('Cookie')

        【讨论】:

        • 非常感谢您的回答!不幸的是,它仍然没有工作。但是,我确定有 cookie。请参阅下面的帖子了解我所做的。
        • 请查看我对原始帖子的编辑以查看我的回复!非常感谢:)
        • @mikolune,查看更新。另外,学习查看源代码——这就是 Python 好的原因——你可以查看源代码,这有时是最好的文档。
        • 非常感谢warvariuc。对于我的特殊问题,我找到了一种不必访问 cookie 的方法(它也有额外的好处)。但这似乎是解决方案。无论如何,我会在几天后尝试,并在这里告诉你进展如何。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-26
        • 2012-06-28
        • 2010-10-30
        • 2011-03-16
        • 1970-01-01
        • 1970-01-01
        • 2018-11-11
        相关资源
        最近更新 更多