Python:urllib/urllib2/httplib 混淆
题
我正在尝试通过在 Python 中编写登录序列脚本来测试 Web 应用程序的功能,但遇到了一些麻烦。
这是我需要做的:
- 使用一些参数和标题执行 POST。
- 遵循重定向
- 检索 HTML 正文。
现在,我对 python 还比较陌生,但是到目前为止我测试过的两件事还没有起作用。首先,我使用了 httplib、putrequest()(在 URL 中传递参数)和 putheader()。这似乎没有遵循重定向。
然后我尝试了 urllib 和 urllib2,将标头和参数作为字典传递。这似乎返回登录页面,而不是我尝试登录的页面,我猜这是因为缺少 cookie 或其他原因。
我错过了一些简单的事情吗?
谢谢。
解决方案
专注于urllib2
为此,它运作良好。不要乱用httplib
,它不是顶级API。
您注意到的是HTTPRedirectHandler
不遵循重定向。
您需要折叠opener
的实例,该实例将捕获并遵循重定向。
此外,您可能希望将默认HTTPHandler
子类化为捕获您将在单元测试中检查的信息。
cookie_handler= urllib2.HTTPCookieProcessor( self.cookies )
redirect_handler= HTTPRedirectHandler()
opener = urllib2.build_opener(redirect_handler,cookie_handler)
然后,您可以使用此<=>对象进行POST和GET,正确处理重定向和Cookie。
您可能还希望添加自己的<=>子类来捕获和记录各种错误代码。
其他提示
这是我对这个问题的看法。
#!/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 /标题。
除了您可能缺少cookie之外,表单中可能还有一些字段您没有发布到网络服务器。最好的方法是从Web浏览器捕获实际的POST。您可以使用 LiveHTTPHeaders 或 WireShark 窥探流量并模仿脚本中的相同行为。
Funkload 也是一款出色的网络应用测试工具。它包装webunit来处理浏览器仿真,然后在顶层提供功能和负载测试功能。