Python urllib3 如何处理Cookie支持?

16 投票
6 回答
25140 浏览
提问于 2025-04-15 20:17

我在研究urllib3,因为它支持连接池,并且线程安全(这样性能更好,特别是在抓取数据的时候),不过它的文档……可以说是非常简陋。urllib2有一个叫build_opener的方法,所以像这样:

#!/usr/bin/python
import cookielib, urllib2
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")

但是urllib3没有build_opener这个方法,所以到目前为止我找到的唯一方法就是手动把它放在请求头里:

#!/usr/bin/python
import urllib3
http_pool = urllib3.connection_from_url("http://example.com")
myheaders = {'Cookie':'some cookie data'}
r = http_pool.get_url("http://example.org/", headers=myheaders)

不过我希望有更好的方法,希望你们中的某个人能告诉我。还有,能不能把这个标签加上“urllib3”?

6 个回答

1

你需要设置的是 'Cookie',而不是 'Set-Cookie',因为 'Set-Cookie' 是由网页服务器设置的。

而且 Cookies 是一种头部信息,所以这样做是完全没问题的。

4

多个cookie会不会有问题呢?

有些服务器会返回多个Set-Cookie的头信息,但urllib3会把这些头信息存储在一个字典里,而字典不允许有重复的键。

httplib2也有类似的问题。

不过,也许并不是这样:实际上,httplib包中的HTTPMessage类的readheaders方法——urllib3和httplib2都在用——有这样一个注释:

如果出现多个同名的头字段,它们会根据RFC 2616第4.2节的规则进行合并:

    Appending each subsequent field-value to the first, each separated
    by a comma. The order in which header fields with the same field-name
    are received is significant to the interpretation of the combined
    field value.

所以不会丢失任何头信息。

不过,如果头信息的值里面有逗号,那就会有问题。我还没搞清楚具体情况,但从浏览RFC 2616(“超文本传输协议——HTTP/1.1”)和RFC 2965(“HTTP状态管理机制”)的内容来看,似乎头信息值里的逗号应该要用引号括起来。

15

你说得对,现在没有更好的方法来解决这个问题。如果你有一个合适的改进方案,我非常乐意接受你的建议。

需要注意的是,urllib3的HTTPConnectionPool是为了与特定主机建立“连接池”,而不是一个有状态的客户端。在这个情况下,把cookie的管理放在连接池之外是有道理的。

  • shazow(urllib3的作者)

撰写回答