如何“保活”? python 中的 cookielib 和 httplib ?

发布于 2024-07-24 22:21:30 字数 147 浏览 8 评论 0原文

在 python 中,我使用 httplib 因为它“保持”http 连接(与 urllib(2) 相反)。 现在,我想将 cookielib 与 httplib 一起使用,但它们似乎互相讨厌! (无法将它们连接在一起)。

有谁知道这个问题的解决方案?

In python, I'm using httplib because it "keep-alive" the http connection (as oppose to urllib(2)). Now, I want to use cookielib with httplib but they seem to hate each other!! (no way to interface them together).

Does anyone know of a solution to that problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷途知返 2024-07-31 22:21:30

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

黑客警报! :)

我会采用其他建议的方式,但我已经做了一个 hack(尽管出于不同的原因),它确实在 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...

You should consider using the Requests library instead at the earliest chance you have to refactor your code. In the mean time;

HACK ALERT! :)

I'd go other suggested way, but I've done a hack (done for different reasons though), which does create an interface between httplib and cookielib.

What I did was creating a fake HTTPRequest with minimal required set of methods, so that CookieJar would recognize it and process cookies as needed. I've used that fake request object, setting all the data needed for cookielib.

Here is the code of the class:

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

Please note, the class has support for HTTPS protocol only (all I needed at the moment).

The code, which used this class was (please note another hack to make response compatible with 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...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文