0

我正在尝试使用 ScraperWiki 的工具抓取一个由 ASP 提供支持的站点。

我想从 BBSmates.com 网站获取特定区号中的 BBS 列表。该站点一次显示 20 个 BBS 搜索结果,因此我必须提交表单才能从一页结果移动到下一页。

这篇博文帮助我入门。我认为下面的代码会抓取 314 区号的 BBS 列表的最后一页(第 79 页)。

但是,我得到的响应是第一页。

url = 'http://bbsmates.com/browsebbs.aspx?BBSName=&AreaCode=314'
br = mechanize.Browser()
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]
response = br.open(url)

html = response.read()

br.select_form(name='aspnetForm')
br.form.set_all_readonly(False)
br['__EVENTTARGET'] = 'ctl00$ContentPlaceHolder1$GridView1'
br['__EVENTARGUMENT'] = 'Page$79'
print br.form
response2 = br.submit()

html2 = response2.read()
print html2

我上面引用的博客文章提到,在他们的情况下,SubmitControl存在问题,因此我尝试禁用此表单上的两个 SubmitControls。

br.find_control("ctl00$cmdLogin").disabled = True

禁用 cmdLogin 生成 HTTP 错误 500。

br.find_control("ctl00$ContentPlaceHolder1$Button1").disabled = True

禁用 ContentPlaceHolder1$Button1 没有任何区别。提交通过了,但是它返回的页面仍然是搜索结果的第 1 页。

值得注意的是,该站点不使用“Page$Next”。

谁能帮我弄清楚我需要做什么才能让 ASPX 表单提交工作?

4

1 回答 1

0

您需要发布页面给出的值(EVENTVALIDATION、VIEWSTATE 等)。

这段代码可以工作(注意它使用了很棒的Requests库而不是 Mechanize)

import lxml.html 
import requests
starturl = 'http://bbsmates.com/browsebbs.aspx?BBSName=&AreaCode=314'
s = requests.session() # create a session object 
r1 = s.get(starturl) #get page 1
html = r1.text
root = lxml.html.fromstring(html)

#pick up the javascript values 
EVENTVALIDATION = root.xpath('//input[@name="__EVENTVALIDATION"]')[0].attrib['value'] 
#find the __EVENTVALIDATION value 
VIEWSTATE = root.xpath('//input[@name="__VIEWSTATE"]')[0].attrib['value'] 
#find the __VIEWSTATE value
# build a dictionary to post to the site with the values we have collected. The __EVENTARGUMENT can be changed to fetch another result page (3,4,5 etc.)
payload = {'__EVENTTARGET': 'ctl00$ContentPlaceHolder1$GridView1','__EVENTARGUMENT':'Page$25','__EVENTVALIDATION':EVENTVALIDATION,'__VIEWSTATE':VIEWSTATE,'__VIEWSTATEENCRYPTED':'','ctl00$txtUsername':'','ctl00$txtPassword':'','ctl00$ContentPlaceHolder1$txtBBSName':'','ctl00$ContentPlaceHolder1$txtSysop':'','ctl00$ContentPlaceHolder1$txtSoftware':'','ctl00$ContentPlaceHolder1$txtCity':'','ctl00$ContentPlaceHolder1$txtState':'','ctl00$ContentPlaceHolder1$txtCountry':'','ctl00$ContentPlaceHolder1$txtZipCode':'','ctl00$ContentPlaceHolder1$txtAreaCode':'314','ctl00$ContentPlaceHolder1$txtPrefix':'','ctl00$ContentPlaceHolder1$txtDescription':'','ctl00$ContentPlaceHolder1$Activity':'rdoBoth','ctl00$ContentPlaceHolder1$drpRPP':'20'}
# post it 
r2 = s.post(starturl, data=payload)
# our response is now page 2 
print r2.text

当您到达结果的末尾(结果第 21 页)时,您必须再次获取 VIEWSTATE 和 EVENTVALIDATION 值(并且每 20 页执行一次)。

请注意,您发布的一些值是空的,还有一些包含值。完整列表是这样的:

'ctl00$txtUsername':'','ctl00$txtPassword':'','ctl00$ContentPlaceHolder1$txtBBSName':'','ctl00$ContentPlaceHolder1$txtSysop':'','ctl00$ContentPlaceHolder1$txtSoftware':'','ctl00$ContentPlaceHolder1$txtCity':'','ctl00$ContentPlaceHolder1$txtState':'','ctl00$ContentPlaceHolder1$txtCountry':'','ctl00$ContentPlaceHolder1$txtZipCode':'','ctl00$ContentPlaceHolder1$txtAreaCode':'314','ctl00$ContentPlaceHolder1$txtPrefix':'','ctl00$ContentPlaceHolder1$txtDescription':'','ctl00$ContentPlaceHolder1$Activity':'rdoBoth','ctl00$ContentPlaceHolder1$drpRPP':'20'

以下是 Scraperwiki 邮件列表上关于类似问题的讨论:https ://groups.google.com/forum/#!topic/scraperwiki/W0Xi7AxfZp0

于 2012-10-29T15:45:15.103 回答