Python urllib3 如何处理Cookie支持?
我在研究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 个回答
你需要设置的是 'Cookie'
,而不是 'Set-Cookie'
,因为 'Set-Cookie'
是由网页服务器设置的。
而且 Cookies 是一种头部信息,所以这样做是完全没问题的。
多个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状态管理机制”)的内容来看,似乎头信息值里的逗号应该要用引号括起来。
你说得对,现在没有更好的方法来解决这个问题。如果你有一个合适的改进方案,我非常乐意接受你的建议。
需要注意的是,urllib3的HTTPConnectionPool是为了与特定主机建立“连接池”,而不是一个有状态的客户端。在这个情况下,把cookie的管理放在连接池之外是有道理的。
- shazow(urllib3的作者)