2013-05-11 80 views
2

我想写一个像Optimizely代理。如果你去http://optimizely.com,你可以尝试任何网站上的Optimizely。这里有一个例子:https://www.optimizely.com/edit#url=espn.comWeb代理喜欢Optimizely

我解剖的页面一点,并注意充当代理实际的URL是edit.optimizely.com:http://edit.optimizely.com/http://espn.go.com/?optimizely_compatibility=false&optimizely_disable=true

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

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

我将如何处理的内容类型,内容长度,其他综合。头,提供了数据返回给用户...

谢谢你任何帮助

+1

这里基本上是我现在有什么server.py:https://gist.github.com/anonymous/8d97c69d2a8cdc52921a和filehelpers.py:https://gist.github.com/anonymous/0e1779b32ecb080d813f所以如果你有这些两个文件,然后运行server.py并转到http:// localhost:8889/http://espn.com/?start = true它可以工作。我认为这不是真正的“正确”方式。这对Optimizely无法为之工作的许多网站无效... – 2013-05-12 01:13:05

回答

0

所以我不知道如何做到这一点龙卷风(我绝对没有0经验),但我可以给你一个例子在烧瓶

首先,我不认为有反正写一个代理,可以让你做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's documentation,特别是关于responses并开始工作。

现在,如果你想部署这个,你必须使用除调试服务器之外的其他东西(比如你现在如何运行它),所以你必须研究不同的解决方案,例如gunicorn ,芹菜等

如果你想继续在Twisted中使用它,我确信Twisted的文档太棒了,它不会比这个特殊的Flask应用程序困难得多。

请注意,如果您曾经觉得您会忘记这是如何工作的,只需添加一个'/'路线并返回一些使用情况信息。它甚至不需要HTML格式的工作。

祝你好运!我希望这是说明你可以做什么以及你需要考虑什么。


编辑

由OP评论之后,我意识到我没有完全理解他的问题。这是一个尝试做得更好的尝试。

要正确设置内容类型,内容长度和其他标题,您需要实际保存来自请求的Response对象。就拿下面的代码:

import requests 

r = requests.get('http://httpbin.org/get') 

现在看标题属性:

r.headers 

是一个字典(可接不区分大小写)头对返回的响应。其中一个标题是Set-Cookie标题(假设您正在抓取的网站设置了Cookie)。

由于您还设置了一个cookie,因此您需要正确构建新的cookie,以便它不会干扰网站,并且可以按照RFC的意图正确添加。

你的字典里会有Content-Length,Content-Type以及他们认为需要发送的所有其他头文件。随心所欲地转发它们。

此外,我没有用Optimizely玩过很多,但我认为通过点击页面上的链接,您不会离开他们的网站。用我上面的天真例子,你最终会离开代理。这就是说,你似乎已经在处理那个案子了,所以你不需要我的帮助。

至于Optimizely究竟是如何做到的,我怀疑他们正在使用大量的JavaScript来编辑和显示它。一切似乎都经历了他们为其使用而设计的“内部”API(edit.optimizely.com),因此并非所有事情都在一个地方发生。我不知道他们的API是如何设计的,也不知道它是如何工作的,但是我怀疑你可以嗅探流量并且可能使用它,如果你收到足够的拦截数据包来确定他们在做什么以及API看起来像什么。

至于请求是否是适当的库:请求是(据说,我从来没有测试过自己)比urllib2快得多。它适用于线程和非线程(或greenlet)的情况。如果您使用会话对象,则会保存所有由espn.com(例如)设置的cookie,并且您的导航将不会受到ESPN的阻碍,从而注意到您没有设置Cookie。但是我们真的不能告诉你它是否是你正在构建的工具的正确库。这完全是你的呼叫。

+0

感谢您对sigmavirus24的回应!所以我已经用我的服务器得到了那么多,我实际上使用http://或https://(取决于请求中的URI)来允许安全和不安全的请求。我甚至为Optimizely设置了一个cookie,以便我可以解析返回的页面中的相关链接。问题是,我该如何做到“正确”。我觉得我在滥用请求库。它并不打算用作代理,龙卷风也可能不是Web框架的最佳解决方案。我或多或少地想知道Optimizely是如何做到这一点 – 2013-05-12 01:01:11

+0

啊,@KangRoodle,我发现你的问题与我的想法大不相同。尽管我只能推测Optimizely,但我会尝试编辑我的答案以包含它。 – 2013-05-12 01:07:00

+0

我添加了一条评论来向你展示基本上我现在拥有的东西...... – 2013-05-12 01:16:04