所以我不确定如何用龙卷风来做到这一点(我对它的经验绝对是 0),但我可以在 Flask 中给你一个例子。
首先,我认为无论如何都不会编写允许您执行http://localhost:8000/http://espn.com
. 请注意,例如,Optimizely 不使用http://espn.com
,而只是espn.com
. 我们也会这样做。
如果你对 Flask 不熟悉,这很简单。这是您可以做到的证明localhost:8000/espn.com
:
from flask import Flask
app = Flask(__name__)
@app.route('/<uri>')
def fake_proxy(uri):
return uri
if __name__ == '__main__':
app.run(debug=True)
将其保存在文件中,proxy1.py
然后执行python proxy1.py
将启动调试服务器,您将能够进入(在浏览器中)http://localhost:5000/espn.com
,它将打印espn.com
到您的浏览器。成功!
要简单地显示网站的内容,您需要做的就是return requests.get('http://' + uri).content
. 我不确定 Flask 中默认设置了什么内容类型,但您不必担心,因为大多数浏览器都会检测到 HTML 并正确显示它。
如果您想准确了解这一点,请查看Flask 的文档,特别是关于响应并开始工作。
现在,如果你想部署它,你将不得不使用除调试服务器之外的其他东西(即你现在如何运行它),所以你必须研究不同的解决方案,例如 gunicorn、celery 等.
如果你想继续在 Twisted 中做这件事,我敢肯定 Twisted 的文档非常棒,而且它不会比这个特定的 Flask 应用程序更难。
请注意,如果您认为您会忘记它是如何工作的,只需为“/”添加一个路由并返回一些使用信息。它甚至不需要 html 格式来工作。
编辑
在 OP 发表评论后,我意识到我并不完全理解他的问题。这是一个做得更好的尝试。
要正确设置 Content-Types、Content-Lengths 和其他标头,您需要实际保存请求中的 Response 对象。以下面的代码为例:
import requests
r = requests.get('http://httpbin.org/get')
现在看看 headers 属性:
r.headers
是响应中返回的标头的字典(可以不区分大小写地访问)。将存在的一个标题是Set-Cookie
标题(假设您正在抓取的网站设置了一个 cookie)。
由于您还设置了 cookie,因此您需要正确构建新 cookie,这样它就不会干扰站点,并且可以按照 RFC 的意图正确附加。
您的字典将包含Content-Length
,Content-Type
和他们认为需要发送的所有其他标题。请随意转发。
另外,我并没有经常使用 Optimizely,但我认为通过单击页面上的链接,您并没有离开他们的网站。在上面我的天真示例中,您最终会离开代理。就是说,您似乎已经按原样处理了该案件,因此您不需要我的帮助。
至于 Optimizely 实际上是如何做的,我怀疑他们使用了大量的 JavaScript 来加载、编辑和显示它。一切似乎都通过了他们为使用而设计的“内部”API ( edit.optimizely.com
),因此并非所有事情都发生在一个地方。
我既不知道他们的 API 是如何设计的,也不知道它是如何工作的,但我怀疑如果你收到足够多的截获数据包以确定它们在做什么以及 API 的样子,你可能会嗅探流量并可能会使用它。
至于 requests 是否是合适的库: requests (据说,我自己从未测试过)比 urllib2 快得多。它在线程和非线程(或greenlet)情况下运行良好。如果您使用会话对象,则espn.com
(例如)设置的所有 cookie 都将被保存,并且您的导航不会受到 ESPN 注意到您没有设置 cookie 的阻碍。但实际上我们无法告诉您它是否适合您正在构建的工具。这完全是你的决定。