【问题标题】:How to add a cookie to the cookiejar in python requests library如何在 python 请求库中的 cookiejar 中添加 cookie
【发布时间】:2013-06-17 22:11:23
【问题描述】:

我正在尝试使用 python requests 1.2.3 库将 cookie 添加到现有 cookiejar。每次我添加新的 cookie 时,jar 中的数据都会被用于新的 cookie。缺少键、缺少值或与不正确的键匹配。我不确定这是请求库错误还是我没有正确发送 cookie。我正在使用以下代码导致 cookiejar 中的 cookie 错误。我是否正确格式化了 cookie?有什么想法吗?

    my_cookie = {
           'domain':'www.mydomain.com',
           'expires':None,
           'name':'COOKIE_NAME',
           'path':'/',
           'value':'the cookie works',
           'version':0
}

s = requests.Session()
requests.utils.add_dict_to_cookiejar(s.cookies, my_cookie)

【问题讨论】:

    标签: cookies python-3.x session-cookies python-requests


    【解决方案1】:

    快速解答

    选项 1

    import requests
    s = requests.session()
    s.cookies.set("COOKIE_NAME", "the cookie works", domain="example.com")
    

    选项 2

    import requests
    s = requests.session()
    # Note that domain keyword parameter is the only optional parameter here
    cookie_obj = requests.cookies.create_cookie(domain="example.com",name="COOKIE_NAME",value="the cookie works")
    s.cookies.set_cookie(cookie_obj)
    

    详细解答

    当最初的问题被问到时,我不知道这种技术是否有效,但理想情况下,您会使用 requests.cookies.create_cookie(name,value,**kwargs) 生成自己的 cookie 对象,然后通过 requests.cookies.RequestsCookieJar.set_cookie(cookie,*args,**kwargs) 将其添加到 cookie jar 中。请参阅源/文档here。

    向请求会话添加自定义 cookie

    >>> import requests
    >>> s = requests.session()
    >>> print(s.cookies)
    <RequestsCookieJar[]>
    >>> required_args = {
            'name':'COOKIE_NAME',
            'value':'the cookie works'
        }
    >>> optional_args = {
        'version':0,
        'port':None,
    #NOTE: If domain is a blank string or not supplied this creates a
    # "super cookie" that is supplied to all domains.
        'domain':'example.com',
        'path':'/',
        'secure':False,
        'expires':None,
        'discard':True,
        'comment':None,
        'comment_url':None,
        'rest':{'HttpOnly': None},
        'rfc2109':False
    }
    >>> my_cookie = requests.cookies.create_cookie(**required_args,**optional_args)
    # Counter-intuitively, set_cookie _adds_ the cookie to your session object,
    #  keeping existing cookies in place
    >>> s.cookies.set_cookie(my_cookie)
    >>> s.cookies
    <RequestsCookieJar[Cookie(version=0, name='COOKIE_NAME', value='the cookie works', port=None, port_specified=False, domain='www.domain.com', domain_specified=True, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)]>
    

    奖励:让我们添加一个超级 cookie 然后删除它

    >>> my_super_cookie = requests.cookies.create_cookie('super','cookie')
    >>> s.cookies.set_cookie(my_super_cookie)
    # Note we have both our previous cookie and our new cookie
    >>> s.cookies
    <RequestsCookieJar[Cookie(version=0, name='super', value='cookie', port=None, port_specified=False, domain='', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False), Cookie(version=0, name='COOKIE_NAME', value='the cookie works', port=None, port_specified=False, domain='www.domain.com', domain_specified=True, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)]>
    # Deleting is simple, note that this deletes the cookie based on the name,
    # if you have multiple cookies with the same name it will raise
    # requests.cookies.CookieConflictError
    >>> del s.cookies['super']
    >>> s.cookies
    <RequestsCookieJar[Cookie(version=0, name='COOKIE_NAME', value='the cookie works', port=None, port_specified=False, domain='www.domain.com', domain_specified=True, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)]>
    

    【讨论】:

    • 我不明白,为什么请求库文档中没有记录?这么简单的案例,却不得不在这里搜索。文档总是使用更复杂的示例。
    • 我也不确定...这也是我心中的一根刺,因此我为什么要亲自去剖析它。很高兴您发现它有帮助!
    • 注意:它是requests.cookies.create_cookie,而不是session.cookies.create_cookie。我犯了那个错误并得到一个错误:'RequestsCookieJar'对象没有属性'create_cookie'
    • 另请注意,您链接的文档页面似乎显示更简洁的session.cookies.set("COOKIE_NAME", "the cookie works", domain="example.com")。
    • 将其与 [隐藏] 代理和标头混合使用,非常适合请求。
    【解决方案2】:

    我通过导入 CookieJar、Cookie 和 cookie 找到了一种方法。在@Lukasa 的帮助下,他向我展示了一个更好的方法。但是,以他的方式,我无法指定“port_specified”、“domain_specified”、“domain_initial_dot”或“path_specified”属性。 “set”方法使用默认值自动执行。我正在尝试抓取一个网站,他们的 cookie 在这些属性中具有不同的值。由于我对这一切都不熟悉,所以我不确定这是否真的很重要。

    my_cookie = {
    "version":0,
    "name":'COOKIE_NAME',
    "value":'true',
    "port":None,
    # "port_specified":False,
    "domain":'www.mydomain.com',
    # "domain_specified":False,
    # "domain_initial_dot":False,
    "path":'/',
    # "path_specified":True,
    "secure":False,
    "expires":None,
    "discard":True,
    "comment":None,
    "comment_url":None,
    "rest":{},
    "rfc2109":False
    }
    
    s = requests.Session()
    s.cookies.set(**my_cookie)
    

    【讨论】:

      【解决方案3】:

      如果您要处理普通的 cookie str:

      def make_cookiejar_dict(cookies_str):
          # alt: `return dict(cookie.strip().split("=", maxsplit=1) for cookie in cookies_str.split(";"))`
          cookiejar_dict = {}
          for cookie_string in cookies_str.split(";"):
              # maxsplit=1 because cookie value may have "="
              cookie_key, cookie_value = cookie_string.strip().split("=", maxsplit=1)
              cookiejar_dict[cookie_key] = cookie_value
          return cookiejar_dict
      
      
      cookies_str = '''nopubuser_abo=1; groupenctype_abo="1="'''
      cj = requests.utils.cookiejar_from_dict(make_cookiejar_dict(cookies_str))
      sess = requests.Session()
      sess.cookies = cj
      

      【讨论】:

      • 您可能应该在; 上拆分,然后在strip 空格上拆分,然后再在= 上拆分。另外,解释一下就好了。
      • 如果 cookie 值中有 '=' 符号,这也会失败,如果该值已经过 base64 编码,则可能会出现这种情况。我意识到这不是很好,并且暗示也导入re,但这对我有用:cj = requests.utils.cookiejar_from_dict(dict(re.match(r'^([^=]+)=(.+)$', p.strip()).groups() for p in plain_cookie.split('; ')))
      • @GregSadetsky 我编辑了答案以处理具有“=”的 cookie 值。请查看
      • maxsplit很好用,我不知道这个说法!谢谢
      【解决方案4】:

      使用内置函数和方法...

      import requests
      
      session = requests.session()
      my_cookies = {'cookie_key': 'cookie_value',
                    'another_cookie_key': 'another_cookie_value'}
      requests.utils.add_dict_to_cookiejar(session.cookies, my_cookies)
      

      您可以根据需要添加任意数量的 cookie。如果需要特殊的header,可以使用这个方法添加。

      my_headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0'}
      session.headers.update(my_headers)
      

      【讨论】:

        猜你喜欢
        • 2018-03-24
        • 2011-06-08
        • 1970-01-01
        • 2011-01-11
        • 2016-01-10
        • 1970-01-01
        • 1970-01-01
        • 2014-10-28
        • 2014-07-17
        相关资源
        最近更新 更多