Python:urllib / urllib2 / httplibの混乱
質問
Pythonでログインシーケンスをスクリプト化することでWebアプリの機能をテストしようとしていますが、いくつかの問題があります。
これは私がする必要があることです:
- いくつかのパラメーターとヘッダーを使用してPOSTを実行します。
- リダイレクトに従う
- HTML本文を取得します。
今、私はpythonには比較的慣れていませんが、これまでにテストした2つのことは機能していません。最初に、putrequest()(URL内のパラメーターを渡す)、およびputheader()でhttplibを使用しました。これはリダイレクトに従わなかったようです。
その後、urllibとurllib2を試し、ヘッダーとパラメーターの両方を辞書として渡しました。これは、ログインしようとしているページではなく、ログインページを返すようです。これは、Cookieの不足などが原因であると思われます。
簡単なものが足りませんか?
ありがとう。
解決
このための urllib2
に焦点を当てると、非常にうまく機能します。 httplib
を混乱させないでください。トップレベルAPIではありません。
注目しているのは、 urllib2
がリダイレクトに従っていないことです。
リダイレクトをキャッチして追跡する HTTPRedirectHandler
のインスタンスを折りたたむ必要があります。
さらに、デフォルトの HTTPRedirectHandler
をサブクラス化して、ユニットテストの一部として確認する情報をキャプチャすることもできます。
cookie_handler= urllib2.HTTPCookieProcessor( self.cookies )
redirect_handler= HTTPRedirectHandler()
opener = urllib2.build_opener(redirect_handler,cookie_handler)
その後、この opener
オブジェクトを使用してPOSTとGETを行い、リダイレクトとCookieを適切に処理できます。
さまざまなエラーコードをキャプチャしてログに記録するために、 HTTPHandler
の独自のサブクラスを追加することもできます。
他のヒント
この問題についての私の見解です。
#!/usr/bin/env python
import urllib
import urllib2
class HttpBot:
"""an HttpBot represents one browser session, with cookies."""
def __init__(self):
cookie_handler= urllib2.HTTPCookieProcessor()
redirect_handler= urllib2.HTTPRedirectHandler()
self._opener = urllib2.build_opener(redirect_handler, cookie_handler)
def GET(self, url):
return self._opener.open(url).read()
def POST(self, url, parameters):
return self._opener.open(url, urllib.urlencode(parameters)).read()
if __name__ == "__main__":
bot = HttpBot()
ignored_html = bot.POST('https://example.com/authenticator', {'passwd':'foo'})
print bot.GET('https://example.com/interesting/content')
ignored_html = bot.POST('https://example.com/deauthenticator',{})
@ S.Lott、ありがとう。あなたの提案は修正されましたが、私にとってはうまくいきました。以下にその方法を示します。
data = urllib.urlencode(params)
url = host+page
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request)
cookies = CookieJar()
cookies.extract_cookies(response,request)
cookie_handler= urllib2.HTTPCookieProcessor( cookies )
redirect_handler= HTTPRedirectHandler()
opener = urllib2.build_opener(redirect_handler,cookie_handler)
response = opener.open(request)
私は最近このことを自分でやらなければなりませんでした。標準ライブラリのクラスのみが必要でした。これが私のコードからの抜粋です:
from urllib import urlencode
from urllib2 import urlopen, Request
# encode my POST parameters for the login page
login_qs = urlencode( [("username",USERNAME), ("password",PASSWORD)] )
# extract my session id by loading a page from the site
set_cookie = urlopen(URL_BASE).headers.getheader("Set-Cookie")
sess_id = set_cookie[set_cookie.index("=")+1:set_cookie.index(";")]
# construct headers dictionary using the session id
headers = {"Cookie": "session_id="+sess_id}
# perform login and make sure it worked
if "Announcements:" not in urlopen(Request(URL_BASE+"login",headers=headers), login_qs).read():
print "Didn't log in properly"
exit(1)
# here's the function I used after this for loading pages
def download(page=""):
return urlopen(Request(URL_BASE+page, headers=headers)).read()
# for example:
print download(URL_BASE + "config")
Mechanizeを提供します( http://wwwsearch.sourceforge.net/mechanize/ ) 一発。 Cookie /ヘッダーを透過的に処理できます。
twill を試してください-ユーザーがコマンドラインインターフェイスからWebを閲覧できるようにする簡単な言語。ツイルを使用すると、フォーム、Cookie、およびほとんどの標準的なWeb機能を使用するWebサイトをナビゲートできます。さらに、 twill は Python
で記述されており、 python API 、例:
from twill import get_browser
b = get_browser()
b.go("http://www.python.org/")
b.showforms()
Cookieが欠落している可能性があるという事実に加えて、WebサーバーにPOSTしていないフォームのフィールドが存在する場合があります。最良の方法は、Webブラウザから実際のPOSTをキャプチャすることです。 LiveHTTPHeaders または WireShark でトラフィックをスヌーピングし、スクリプト内の同じ動作を模倣します。
Funkload も優れたWebアプリテストツールです。ブラウザーエミュレーションを処理するためにwebunitをラップしてから、機能と負荷テストの両方の機能を提供します。