2015-06-29 44 views
3

编辑(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' 

成功修改这两个值可将我登录到主页面。我希望这可以帮助别人!

回答

0

感谢您使用Firebug(或Chrome内置的开发人员工具)来检查请求内容并查看实际上将哪些表单字段邮寄回服务器的提示。我不得不添加一个额外的字段{'SubmitLogin':'Sign In'}让我的服务器进行身份验证。