2013-05-11 51 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