解决Python Requests库中处理重定向时的多重Cookie问题

2023-11-16 10:34:41 浏览数 (2)

问题背景

在更新至f73bda06e9版本后,用户发现某些请求会引发CookieConflictError。具体来说,任何设置饼干且重定向到设置相同饼干的页面的请求都会引发CookieConflictError。

重现步骤

1、更新Requests至上述版本。

2、从中国以外的任何地方向baidu发送请求。

预期行为

Requests应该返回200 OK,并在历史记录中包含302。

实际行为

代码语言:javascript复制
>>> import requests
>>> r = requests.get('http://baidu/')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "requests/api.py", line 55, in get
    return request('get', url, **kwargs)
  File "requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "requests/sessions.py", line 312, in request
    resp = self.send(prep, **send_kwargs)
  File "requests/sessions.py", line 426, in send
    history = [resp for resp in gen] if allow_redirects else []
  File "requests/sessions.py", line 163, in resolve_redirects
    resp.cookies.update(cookiejar)
  File "venv/lib/python2.7/_abcoll.py", line 494, in update
    self[key] = other[key]
  File "requests/cookies.py", line 246, in __getitem__
    return self._find_no_duplicates(name)
  File "requests/cookies.py", line 285, in _find_no_duplicates
    raise CookieConflictError('There are multiple cookies with name, %r' % (name))
requests.cookies.CookieConflictError: There are multiple cookies with name, 'NID'

明显是由于在做出更改后发生的。Lukasa在2013-02-14 00:11评论道:@sigmavirus24 我在这个问题上@了你 sigmavirus24在2013-02-14 02:56评论道:可恶。我担心最后一行可能会引起问题,但我没有找到像GitHub这样的网站,也没有想到要测试它。我认为GitHub可能是异常。

解决方案

要解决此问题,需要在更新后的Requests中修改代码,以防止在重定向时设置相同的饼干。具体来说,可以使用一个字典来跟踪已经设置的饼干,并在重定向时检查是否已经设置过相同的饼干。如果已经设置过相同的饼干,则不设置新的饼干。这样可以避免引发CookieConflictError。

解决方案示例:

代码语言:javascript复制
import requests

# 创建一个字典来跟踪已经设置的饼干
cookie_dict = {}

def custom_redirect(session, resp, **kwargs):
    # 获取重定向的URL
    redirect_url = resp.headers['Location']

    # 检查是否已经设置过相同的饼干
    if 'Set-Cookie' in resp.headers:
        cookie = resp.headers['Set-Cookie']
        cookie_name = cookie.split('=')[0]
        if cookie_name not in cookie_dict:
            # 如果没有设置过相同的饼干,将其添加到字典中
            cookie_dict[cookie_name] = cookie
            # 执行重定向
            session.get(redirect_url, **kwargs)
    else:
        # 如果没有设置饼干,直接执行重定向
        session.get(redirect_url, **kwargs)

# 创建一个会话对象,并设置自定义重定向函数
with requests.Session() as session:
    session.redirect_hook = custom_redirect

    # 发送请求
    r = session.get('http://baidu/')

通过以上修改,我们可以自定义重定向过程,在重定向时检查和处理相同的饼干,从而避免引发CookieConflictError。这种方法可以确保请求能够正常执行,并且不会出现多重Cookie的问题。

总结而言,解决Python Requests库中的CookieConflictError问题涉及对重定向过程的自定义控制,以防止在重定向时设置相同的饼干。通过使用字典来跟踪已经设置的饼干,并在重定向时进行检查和处理,可以有效地解决这一问题,确保请求能够正常执行。

0 人点赞