【发布时间】:2014-06-27 22:39:00
【问题描述】:
我正在使用 Scrapy 来抓取身份验证屏幕后面的一些金子。该网站使用ASP.net,而ASP 的表单中到处都是一些愚蠢的隐藏字段(如__VIEWSTATE、__EVENTTARGET)。
当我调用 FormRequest.from_response(response,... 时,我希望它会自动从响应中读取这些隐藏字段并将它们填充到 formdata 字典中 - 这是 Scrapy's FormRequest 文档所说的 应该做。
但如果是这样,那为什么登录过程只有在我明确列出这些字段并填充它们时才起作用?
class ItsyBitsy(Spider):
name = "itsybitsy"
allowed_domains = ["website.com"]
start_urls = ["http://website.com/cpanel/Default.aspx"]
def parse(self, response):
# Performs authentication to get past the login form
sel = Selector(response)
return [FormRequest.from_response(response,
formdata={
'tb_Username':'admin',
'tb_Password':'password',
# The following fields should be auto populated, right?
# So why does removing 'em break the login (w/500 Server Error)
'__VIEWSTATE':
sel.xpath("//input[@name='__VIEWSTATE']/@value").extract(),
'__EVENTVALIDATION':
sel.xpath("//input[@name='__EVENTVALIDATION']/@value").extract(),
'__EVENTTARGET': 'b_Login'
},
callback=self.after_login,
clickdata={'id':'b_Login'},
dont_click=True)]
def after_login(self, response):
# Mmm, scrumptious
pass
编辑:添加表单 HTML
<form id="form1" action="Default.aspx" method="post" name="form1">
<div>
<input type="hidden" value="" id="__EVENTTARGET" name="__EVENTTARGET">
<input type="hidden" value="" id="__EVENTARGUMENT" name="__EVENTARGUMENT">
<input type="hidden" value="/wEPDwULLTE2OTg2NjA1NTAPZBYCAgMPZBYGAgMPD2QWAh4Kb25rZXlwcmVzcwUlcmV0dXJuIGNsaWNrQnV0dG9uKGV2ZW50LCAnYl9Mb2dpbicpO2QCBQ8PZBYCHwAFJXJldHVybiBjbGlja0J1dHRvbihldmVudCwgJ2JfTG9naW4nKTtkAgcPD2QWAh4Hb25jbGljawUPcmV0dXJuIGxvZ2luKCk7ZGRKt/WTOQThVTxB9Y0QcIuRqylCIw==" id="__VIEWSTATE" name="__VIEWSTATE">
</div>
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
<div>
<input type="hidden" value="/wEWBAK0o8DDCQLxz5rcDwLF8dCIDALHyYWSA+rA4VJNaEpFIycMDHQPUOz393TI" id="__EVENTVALIDATION" name="__EVENTVALIDATION">
<input type="text" onkeypress="return clickButton(event, 'b_Login');" size="28" class="textfield-text" id="tb_Username" name="tb_Username">
<input type="password" onkeypress="return clickButton(event, 'b_Login');" size="28" class="textfield-text" id="tb_Password" name="tb_Password">
<a href="javascript:__doPostBack('b_Login','')" class="button-link" id="b_Login" onclick="return login();">Login</a>
</form>
【问题讨论】:
-
请在输入的位置显示
form标签的内容。 -
@alecxe 完成。应该不会有太大区别,因为我显然可以使用 XPATH 检索它吗?
-
我猜有多种形式。可以将
'formname':'form1'添加到formdata 字典中进行测试吗? -
@sp1der 它没有按预期工作。身份验证后请求下一页时,我得到一个
302回到登录页面。
标签: python html forms web-scraping scrapy