编辑(10/30):解决方案发现在这篇文章的底部。通过Python的机械化过去一个登录屏幕
大家好,
我是新来的“网络”刮现场,并一直试图在GISIS与Python从页面抽取数据。虽然我最初试图用requests
来做到这一点,但是D8Amonk's post on SO让我看到了mechanize
,这在大多数情况下工作得很好。
我能够通过添加kumar的帖子中找到的标题来绕过我收到的最初的403个错误,但现在面临无法超越GISIS的登录屏幕到其实际的问题,相关的网页。
Julian Todd在ScraperWiki的精彩帖子帮助我了解了如何禁用恼人的提交控件和处理页面的_doPostBack()机制。不幸的是,登录页面仍然忽略机械化人员完成表单提交的尝试 - 它不承认已输入权限,用户名和密码。
我的代码片段如下如下:
import os
import sys
import webbrowser
import mechanize
import urllib2
import cookielib
from bs4 import BeautifulSoup
header = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'Accept-Encoding': 'none',
'Accept-Language': 'en-US,en;q=0.8',
'Connection': 'keep-alive'}
request = urllib2.Request('https://gisis.imo.org/Public/SHIPS/Default.aspx', None, header)
...
jar = cookielib.CookieJar()
browser = mechanize.Browser()
browser.set_cookiejar(jar)
browser.set_handle_robots(False)
browser.open(request)
browser.select_form(nr=0)
browser.form.set_all_readonly(False)
browser.form['ctl00$cpMain$ddlAuthorityType'] = ['PUBLIC']
browser.form['ctl00$cpMain$txtUsername'] = username
browser.form['ctl00$cpMain$txtPassword'] = password
browser.find_control('ctl00$cpMain$cbxRemember').selected = False
browser.find_control('ctl00$cpMain$btnRegister').disabled = True
browser["__EVENTTARGET"] = "lnkNext"
browser["__EVENTARGUMENT"] = ""
resp = browser.submit()
print '-- Request Made Successfully --'
return resp.read()
resp.read()
然后写入到一个HTML文件,并在Firefox打开。对browser.form[...]
行进行评论和取消注释引发了一个有趣的发现:如果表单提交中包含权威(本例中为“Public”),则网页将识别权威机构,但是抱怨必须输入用户名和密码被输入。
但是,如果权限行被注释掉,则生成的网页将认识到已输入用户名和密码,但会要求选择权限(在这种情况下,用户名字段将被填充输出正确,但密码字段将为空白;我不确定这是否合意或预期的行为)。同样,只要管理局行仍然被注释掉,那么我可以注释掉我的代码中的用户名或密码行,并且生成的网页将要求权威和,无论其他字段已被注释掉(即if我只提交密码,然后页面会要求授权和用户名)。
有没有人对我可能做错的事情有什么建议,或者在哪里看?这似乎是一个相当不寻常的问题 - 在Google上搜索未能产生其他人遇到的任何类似问题。
P.S.这是我在StackOverflow上的第一篇文章。我试图附加图片来解释我所描述的场景,但显然缺乏发布图片所需的代表。如果我过分冗长或做错了错误,即格式化我的文章,请大声道歉 - 请纠正我的错误!
编辑(10/30):回到这个项目后,转移到其他东西,并找出解决方案。下面的解决方案:
这实际上并不像我想象的那么复杂。修改__EVENTTARGET
和__EVENTARGUMENT
是不必要的。相反,__VIEWSTATE
和__VIEWSTATEGENERATOR
都需要修改。通过检查Firebug中发出的成功POST请求,找到了正确的使用值。示例代码如下:
browser.form['__VIEWSTATE'] = 'blablabla'
browser.form['__VIEWSTATEGENERATOR'] = 'blablabla'
成功修改这两个值可将我登录到主页面。我希望这可以帮助别人!