我在python中设置HTTP代理来过滤Web内容。我在StackOverflow上找到了good example,它使用Twisted来完成此操作。但是,我需要另一个代理来访问网络。因此,代理需要将请求转发给另一个代理。使用twisted.web.proxy执行此操作的最佳方法是什么?
我发现a related question需要类似的内容,但是来自反向代理。
我最好的猜测是,应该可以通过修改或子类化twisted.web.proxy.ProxyClient
来连接到下一个代理而不是直接连接到Web来构建链式代理。不幸的是,我没有在文档中找到有关如何执行此操作的任何线索。
到目前为止我的代码(cite):
from twisted.python import log
from twisted.web import http, proxy
class ProxyClient(proxy.ProxyClient):
def handleResponsePart(self, buffer):
proxy.ProxyClient.handleResponsePart(self, buffer)
class ProxyClientFactory(proxy.ProxyClientFactory):
protocol = ProxyClient
class ProxyRequest(proxy.ProxyRequest):
protocols = dict(http=ProxyClientFactory)
class Proxy(proxy.Proxy):
requestFactory = ProxyRequest
class ProxyFactory(http.HTTPFactory):
protocol = Proxy
portstr = "tcp:8080:interface=localhost" # serve on localhost:8080
if __name__ == '__main__':
import sys
from twisted.internet import endpoints, reactor
log.startLogging(sys.stdout)
endpoint = endpoints.serverFromString(reactor, portstr)
d = endpoint.listen(ProxyFactory())
reactor.run()
答案 0 :(得分:0)
使用Twisted实际上并不难实现。让我举个简单的例子。
假设第一个代理是proxy1.py
,就像您在问题中粘贴的代码一样;
第二个代理是proxy2.py
。
对于proxy1.py
,您只需要覆盖类process
的{{1}}函数。像这样:
ProxyRequest
对于class ProxyRequest(proxy.ProxyRequest):
def process(self):
parsed = urllib_parse.urlparse(self.uri)
protocol = parsed[0]
host = parsed[1].decode('ascii')
port = self.ports[protocol]
if ':' in host:
host, port = host.split(':')
port = int(port)
rest = urllib_parse.urlunparse((b'', b'') + parsed[2:])
if not rest:
rest = rest + b'/'
class_ = self.protocols[protocol]
headers = self.getAllHeaders().copy()
if b'host' not in headers:
headers[b'host'] = host.encode('ascii')
self.content.seek(0, 0)
s = self.content.read()
clientFactory = class_(self.method, rest, self.clientproto, headers, s, self)
if (NeedGoToSecondProxy):
self.reactor.connectTCP(your_second_proxy_server_ip, your_second_proxy_port, clientFactory)
else:
self.reactor.connectTCP(host, port, clientFactory)
,您只需要设置另一个简单代理。但是需要注意一个问题,您可能需要再次覆盖proxy2.py
中的process
函数,因为proxy2.py
在代理转发(链)之后可能无效。
例如,原始self.uri
应为self.uri
,您可能会在第二个代理处找到它http://www.google.com/something?para1=xxx
。因此,您需要从/something?para1=xxx
中提取主机信息并补充self.headers
,以便您的第二个代理可以正常将其发送到正确的目的地。