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”标记它吗?
解决方案
你是对的,现在没有更好的方法来做到这一点。如果您有一致的改进,我将非常乐意接受补丁。
需要记住的一件事是,urllib3 的 HTTPConnectionPool 旨在成为特定主机的“连接池”,而不是有状态客户端。在这种情况下,将 cookie 跟踪保留在实际池之外是有意义的。
- shazow(urllib3的作者)
其他提示
多个cookie不存在问题吗?
有些服务器返回多个 Set-Cookie 标头,但 urllib3 将标头存储在字典中,而字典不允许具有相同键的多个条目。
httplib2也有类似的问题。
或者可能不是:事实证明,httplib 包中 HTTPMessage 类的 readheaders 方法(urllib3 和 httplib2 都使用该方法)具有以下注释:
如果出现多个同名头字段,则根据 RFC 2616 sec 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 状态管理机制”),我得到的印象是标头中的任何逗号值应该被引用。
您需要设置'Cookie'
不'Set-Cookie'
,'Set-Cookie'
由Web服务器设置。
和Cookies是头一个,所以它没有错,这样做的方式。
您应该使用请求库。它使用urllib3但使事情如添加饼干微不足道的。
https://github.com/kennethreitz/requests
import requests
r1 = requests.get(url, cookies={'somename':'somevalue'})
print(r1.content)
可以使用一个这样的代码:
def getHtml(url):
http = urllib3.PoolManager()
r = http.request('GET', url, headers={'User-agent':'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36','Cookie':'cookie_name=cookie_value'})
return r.data #HTML
您应该替换cookie_name和cookie_value