2

我正在尝试编写像 Optimizely 这样的代理。如果你去,http://optimizely.com你可以在任何网站上尝试 Optimizely。这是一个例子:https://www.optimizely.com/edit#url=espn.com

我已经对页面进行了一些剖析,并注意到充当代理的实际 URL 位于edit.optimizely.com:http://edit.optimizely.com/http://espn.go.com/?optimizely_compatibility=错误&optimizely_disable=true

此页面上的许多请求返回到 edit.optimizely.com/{uri},并且似乎他们使用 cookie 来保留实际域(您可以在 cookie 中看到last_path=http://espn.go.com/;),并且 url 在服务器上被代理。

我编写了一个使用 [requests][2] 作为代理的龙卷风应用程序,其行为方式与 Optimizely 代理类似,但我知道这不是请求的意图,而且它在许多网站上都失败了。我想知道实现类似东西的“正确”方式。我知道我可以使用Twisted轻松编写代理,然后更改系统上的全局代理设置以使用它,但我不确定如何编写一个返回 espn.com 内容的应用程序:http://localhost:8000/http://espn.com没有滥用诸如请求之类的东西...(即return requests.get('http://espn.com').content

我将如何处理内容类型、内容长度和其他杂项。标头,将数据传递回用户...

4

1 回答 1

0

所以我不确定如何用龙卷风来做到这一点(我对它的经验绝对是 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 的阻碍。但实际上我们无法告诉您它是否适合您正在构建的工具。这完全是你的决定。

于 2013-05-12T00:46:03.790 回答