pythontwisted框架HttpClient访问代理吗?

发布于 2024-08-09 16:39:45 字数 321 浏览 3 评论 0原文

我需要使用访问网页

twisted.web.client.getPage()

或类似的方法从已知地址(即:www.google.com)下载网页,问题是:我位于代理服务器后面,我找不到任何有关如何下载网页的说明配置扭曲或工厂来使用我的代理,有什么想法吗?

请记住,我必须指定用户、密码、主机和端口。 在我的 Linux 机器上,我将 http_proxyhttps_proxy 设置为 http://user:pwd@ip:port

提前谢谢。

I need to access a webpage using

twisted.web.client.getPage()

or a similar method to download a webpage from a known address (ie:www.google.com), the problem is: I am behind a proxy server and I couldn't find anywhere explanations on how to configure twisted or factories to use my proxy, any ideas?

Bear in mind I have to specify user, password, host and port.
On my linux machine I setup http_proxy and https_proxy to http://user:pwd@ip:port

Thankyou in advance.

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

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

发布评论

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

评论(4

云仙小弟 2024-08-16 16:39:45
from twisted.internet import reactor
from twisted.web import client

def processResult(page):
    print "I got some data", repr(page)
    reactor.callLater(0.1, reactor.stop)
def dealWithError(err):
    print err.getErrorMessage()
    reactor.callLater(0.1, reactor.stop)

class ProxyClientFactory(client.HTTPClientFactory):
    def setURL(self, url):
        client.HTTPClientFactory.setURL(self, url)
        self.path = url

factory = ProxyClientFactory('http://url_you_want')
factory.deferred.addCallbacks(processResult, dealWithError)

reactor.connectTCP('proxy_address', 3142, factory)
reactor.run()
from twisted.internet import reactor
from twisted.web import client

def processResult(page):
    print "I got some data", repr(page)
    reactor.callLater(0.1, reactor.stop)
def dealWithError(err):
    print err.getErrorMessage()
    reactor.callLater(0.1, reactor.stop)

class ProxyClientFactory(client.HTTPClientFactory):
    def setURL(self, url):
        client.HTTPClientFactory.setURL(self, url)
        self.path = url

factory = ProxyClientFactory('http://url_you_want')
factory.deferred.addCallbacks(processResult, dealWithError)

reactor.connectTCP('proxy_address', 3142, factory)
reactor.run()
⊕婉儿 2024-08-16 16:39:45

为了让 nosklo 的解决方案发挥作用,您需要为“401”创建另一个处理程序,以指示需要身份验证。尝试这样的操作

def checkAuthError(self,failure,url):
    failure.trap(error.Error)
    if failure.value.status == '401':
        username = raw_input("User name: ")
        password = getpass.getpass("Password: ")
        auth = base64.encodestring("%s:%s" %(username, password))
        header = "Basic " + auth.strip()
        return client.getPage(
            url, headers={"Authorization": header})
    else:
        return failure

这将提示操作员在命令行提供信息,或者您可以以您选择的其他方式提供用户名和密码。确保这是作为 Errback 添加的第一个处理程序,然后再添加任何其他处理程序(甚至是 Callback)。这还需要更多的进口; 'base64'、'getpass' 和 'error' 与命令行提示一起使用。

To get nosklo's solution to work you will need to create another handler for the '401' that indicates that authentication is required. Try something like this

def checkAuthError(self,failure,url):
    failure.trap(error.Error)
    if failure.value.status == '401':
        username = raw_input("User name: ")
        password = getpass.getpass("Password: ")
        auth = base64.encodestring("%s:%s" %(username, password))
        header = "Basic " + auth.strip()
        return client.getPage(
            url, headers={"Authorization": header})
    else:
        return failure

This will prompt the operator to supply the information at the command line, or you couple could supply the username and password in another way of your choosing. Make sure this is the first handler added as an Errback, before any other handlers are added even the Callback. This also requires a few more imports; 'base64', 'getpass', and 'error' to work with the command line prompts.

梦断已成空 2024-08-16 16:39:45

我必须使用基本身份验证执行类似的操作,因为身份验证请求的示例代码在这里不起作用,但可以使用的版本是:

import base64

from twisted.internet import defer, reactor
from twisted.web import client, error, http

from ubuntuone.devtools.testcases.squid import SquidTestCase

# ignore common twisted lint errors
# pylint: disable=C0103, W0212


class ProxyClientFactory(client.HTTPClientFactory):
    """Factory that supports proxy."""

    def __init__(self, proxy_url, proxy_port, url, headers=None):
        self.proxy_url = proxy_url
        self.proxy_port = proxy_port
        client.HTTPClientFactory.__init__(self, url, headers=headers)

    def setURL(self, url):
        self.host = self.proxy_url
        self.port = self.proxy_port
        self.url = url
        self.path = url


class ProxyWebClient(object):
    """Provide useful web methods with proxy."""

    def __init__(self, proxy_url=None, proxy_port=None, username=None,
            password=None):
        """Create a new instance with the proxy settings."""
        self.proxy_url = proxy_url
        self.proxy_port = proxy_port
        self.username = username
        self.password = password

    def _process_auth_error(self, failure, url, contextFactory):
        """Process an auth failure."""
        # we try to get the page using the basic auth
        failure.trap(error.Error)
        if failure.value.status == str(http.PROXY_AUTH_REQUIRED):
            auth = base64.b64encode('%s:%s' % (self.username, self.password))
            auth_header = 'Basic ' + auth.strip()
            factory = ProxyClientFactory(self.proxy_url, self.proxy_port, url,
                    headers={'Proxy-Authorization': auth_header})
            # pylint: disable=E1101
            reactor.connectTCP(self.proxy_url, self.proxy_port, factory)
            # pylint: enable=E1101
            return factory.deferred
        else:
            return failure

    def get_page(self, url, contextFactory=None, *args, **kwargs):
        """Download a webpage as a string.

        This method relies on the twisted.web.client.getPage but adds and extra
        step. If there is an auth error the method will perform a second try
        so that the username and password are used.
        """
        scheme, _, _, _ = client._parse(url)
        factory = ProxyClientFactory(self.proxy_url, self.proxy_port, url)
        if scheme == 'https':
            from twisted.internet import ssl
            if contextFactory is None:
                contextFactory = ssl.ClientContextFactory()
            # pylint: disable=E1101
            reactor.connectSSL(self.proxy_url, self.proxy_port,
                               factory, contextFactory)
            # pylint: enable=E1101
        else:
            # pylint: disable=E1101
            reactor.connectTCP(self.proxy_url, self.proxy_port, factory)
            # pylint: enable=E1101
        factory.deferred.addErrback(self._process_auth_error, url,
                                    contextFactory)
        return factory.deferred

I had to do something similar using base auth, since the example code for the auth request did not work here is a version that works:

import base64

from twisted.internet import defer, reactor
from twisted.web import client, error, http

from ubuntuone.devtools.testcases.squid import SquidTestCase

# ignore common twisted lint errors
# pylint: disable=C0103, W0212


class ProxyClientFactory(client.HTTPClientFactory):
    """Factory that supports proxy."""

    def __init__(self, proxy_url, proxy_port, url, headers=None):
        self.proxy_url = proxy_url
        self.proxy_port = proxy_port
        client.HTTPClientFactory.__init__(self, url, headers=headers)

    def setURL(self, url):
        self.host = self.proxy_url
        self.port = self.proxy_port
        self.url = url
        self.path = url


class ProxyWebClient(object):
    """Provide useful web methods with proxy."""

    def __init__(self, proxy_url=None, proxy_port=None, username=None,
            password=None):
        """Create a new instance with the proxy settings."""
        self.proxy_url = proxy_url
        self.proxy_port = proxy_port
        self.username = username
        self.password = password

    def _process_auth_error(self, failure, url, contextFactory):
        """Process an auth failure."""
        # we try to get the page using the basic auth
        failure.trap(error.Error)
        if failure.value.status == str(http.PROXY_AUTH_REQUIRED):
            auth = base64.b64encode('%s:%s' % (self.username, self.password))
            auth_header = 'Basic ' + auth.strip()
            factory = ProxyClientFactory(self.proxy_url, self.proxy_port, url,
                    headers={'Proxy-Authorization': auth_header})
            # pylint: disable=E1101
            reactor.connectTCP(self.proxy_url, self.proxy_port, factory)
            # pylint: enable=E1101
            return factory.deferred
        else:
            return failure

    def get_page(self, url, contextFactory=None, *args, **kwargs):
        """Download a webpage as a string.

        This method relies on the twisted.web.client.getPage but adds and extra
        step. If there is an auth error the method will perform a second try
        so that the username and password are used.
        """
        scheme, _, _, _ = client._parse(url)
        factory = ProxyClientFactory(self.proxy_url, self.proxy_port, url)
        if scheme == 'https':
            from twisted.internet import ssl
            if contextFactory is None:
                contextFactory = ssl.ClientContextFactory()
            # pylint: disable=E1101
            reactor.connectSSL(self.proxy_url, self.proxy_port,
                               factory, contextFactory)
            # pylint: enable=E1101
        else:
            # pylint: disable=E1101
            reactor.connectTCP(self.proxy_url, self.proxy_port, factory)
            # pylint: enable=E1101
        factory.deferred.addErrback(self._process_auth_error, url,
                                    contextFactory)
        return factory.deferred
江南月 2024-08-16 16:39:45

我们选择使用 http_proxy 环境变量。我们遇到了重定向问题,重定向并不总是被接收,或者更确切地说是以正确的方式被接收。也就是说,nosklo 的回应确实很有帮助!

import os
from twisted.web import client

class ProxyClientFactory(client.HTTPClientFactory):
    def setURL(self, url):
        '''More sensitive to redirects that can happen, that
        may or may not be proxied / have different proxy settings.'''
        scheme, host, port, path = client._parse(url)
        proxy = os.environ.get('%s_proxy' % scheme)
        if proxy:
            scheme, host, port, path = client._parse(proxy)
            self.scheme = scheme
            self.host = host
            self.port = port
            self.path = url
            self.url = url
        else:
            client.HTTPClientFactory.setURL(self, url)

factory = ProxyClientFactory(url)
# Callback configuration
# If http_proxy or https_proxy, or whatever appropriate proxy
# is set, then we should try to honor that. We do so simply 
# by overriding the host/port we'll connect to. The client
# factory, BaseRequestServicer takes care of the rest
scheme, host, port, path = client._parse(url)
proxy = os.environ.get('%s_proxy' % scheme)
if proxy:
    scheme, host, port, path = client._parse(proxy)
reactor.connectTCP(host, port, factory)

We chose to use the http_proxy environment variable. We were having trouble with redirections not always getting picked up, or rather getting picked up in the right way. That said, nosklo's response really helped!

import os
from twisted.web import client

class ProxyClientFactory(client.HTTPClientFactory):
    def setURL(self, url):
        '''More sensitive to redirects that can happen, that
        may or may not be proxied / have different proxy settings.'''
        scheme, host, port, path = client._parse(url)
        proxy = os.environ.get('%s_proxy' % scheme)
        if proxy:
            scheme, host, port, path = client._parse(proxy)
            self.scheme = scheme
            self.host = host
            self.port = port
            self.path = url
            self.url = url
        else:
            client.HTTPClientFactory.setURL(self, url)

factory = ProxyClientFactory(url)
# Callback configuration
# If http_proxy or https_proxy, or whatever appropriate proxy
# is set, then we should try to honor that. We do so simply 
# by overriding the host/port we'll connect to. The client
# factory, BaseRequestServicer takes care of the rest
scheme, host, port, path = client._parse(url)
proxy = os.environ.get('%s_proxy' % scheme)
if proxy:
    scheme, host, port, path = client._parse(proxy)
reactor.connectTCP(host, port, factory)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文