我需要使用
访问网页twisted.web.client.getPage()
或类似的方法从已知地址(即:www.google.com)下载网页,问题是:我在代理服务器后面,我无法找到关于如何配置扭曲或工厂的任何解释使用我的代理,任何想法?
请记住,我必须指定用户,密码,主机和端口。
在我的linux机器上,我将http_proxy
和https_proxy
设置为http://user:pwd@ip:port
提前谢谢你。
答案 0 :(得分:3)
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()
答案 1 :(得分:1)
要使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添加的处理程序,在添加任何其他处理程序之前,甚至是回调。这还需要更多的进口; 'base64','getpass'和'error'可以使用命令行提示。
答案 2 :(得分:1)
我必须使用base auth做类似的事情,因为auth请求的示例代码在这里不起作用是一个有效的版本:
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
答案 3 :(得分:0)
我们选择使用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)