2009-06-19 58 views
1

在python中,我使用httplib是因为它保持http连接(与urllib(2)相反)。现在,我想用httplib使用cookielib,但他们似乎互相讨厌! (没有办法将它们连接在一起)。如何在python中用cookielib和httplib保持活力?

有没有人知道解决这个问题?

+0

使用httplib的要求? cookielib与urllib2协同工作,您可以添加自己的保持活动标题。 – 2009-06-19 13:46:15

+0

为了保持所有内容的一致性,您可能需要将lower()和has_header和get_headers键的所有引用更改为lowerdate( – 2010-08-09 05:53:04

回答

2

你应该考虑使用Requests库,而不是在你重构你的代码最早的机会。同时;

HACK ALERT! :)

我会采取其他建议的方式,但我做了一个黑客(做了不同的原因,虽然),这确实创建httplibcookielib之间的接口。

我所做的是用最少的必需方法创建一个假的HTTPRequest,以便CookieJar可以识别它并根据需要处理cookie。我使用了假的请求对象,设置了cookielib所需的所有数据。

下面是类代码:

class HTTPRequest(object): 
""" 
Data container for HTTP request (used for cookie processing). 
""" 

    def __init__(self, host, url, headers={}, secure=False): 
     self._host = host 
     self._url = url 
     self._secure = secure 
     self._headers = {} 
     for key, value in headers.items(): 
      self.add_header(key, value) 

    def has_header(self, name): 
     return name in self._headers 

    def add_header(self, key, val): 
     self._headers[key.capitalize()] = val 

    def add_unredirected_header(self, key, val): 
     self._headers[key.capitalize()] = val 

    def is_unverifiable(self): 
     return True 

    def get_type(self): 
     return 'https' if self._secure else 'http' 

    def get_full_url(self): 
     port_str = "" 
     port = str(self._host[1]) 
     if self._secure: 
      if port != 443: 
       port_str = ":"+port 
     else: 
      if port != 80: 
       port_str = ":"+port 
     return self.get_type() + '://' + self._host[0] + port_str + self._url 

    def get_header(self, header_name, default=None): 
     return self._headers.get(header_name, default) 

    def get_host(self): 
     return self._host[0] 

    get_origin_req_host = get_host 

    def get_headers(self): 
     return self._headers 

请注意,这个类有只HTTPS协议的支持(所有我需要的时刻)。

它使用这个类是(请注意其他的黑客攻击,使与cookielib响应兼容)的代码,:

cookies = CookieJar() 

headers = { 
    # headers that you wish to set 
} 

# construct fake request 
fake_request = HTTPRequest(host, request_url, headers) 

# add cookies to fake request 
cookies.add_cookie_header(fake_request) 

# issue an httplib.HTTPConnection based request using cookies and headers from the fake request 
http_connection.request(type, request_url, body, fake_request.get_headers()) 

response = http_connection.getresponse() 

if response.status == httplib.OK: 
    # HACK: pretend we're urllib2 response 
    response.info = lambda : response.msg 

    # read and store cookies from response 
    cookies.extract_cookies(response, fake_request) 

    # process response...