scrapy分页抓取网页(ASP.js代码怎么封装,不如直接抓包看看传递什么参数 )
优采云 发布时间: 2022-03-31 04:13scrapy分页抓取网页(ASP.js代码怎么封装,不如直接抓包看看传递什么参数
)
以上文章介绍了scrapy爬取的一般架构,本文文章解释了一些技术问题。
一、如何处理 ASP.NET 分页
我们以深圳房地产信息系统为例。
因为之前一直在写ASP.NET,所以很多.NET控件都是通过拖拽来实现的。很多代码可以省去编写过程,自动生成。这里的下一页操作是通过自动生成的js代码,scrapy框架无法执行js代码。但是我们知道他执行了_doPostBack函数,我们来看看_doPostBack是怎么定义的。
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
看看form1是怎么定义的
里面有很多隐藏的控件,里面有很多值,都是自动生成的。我不知道这意味着什么。
但是我们知道他的原理是再次向这个页面发送一个POST请求进行分页。所以URL地址没有变化。既然有POST操作,那传入什么参数。一闪而过,与其研究如何封装JS代码,不如直接抓包看看传了什么参数。
这里使用常用的wireshark,简单易上手,一目了然。
当我们点击next时,我们可以看到发送了一个HTTP请求并执行了POST方法。
进一步展开。所有参数都一一列出。传递参数也隐藏在页面上。
回去看看我为递归查询编写的分页代码。
def parse(self, response):
context = response.xpath('//tr[@bgcolor="#F5F9FC"]/td[3]')
dbhelp=RishomePipeline()
for item in context:
title=item.xpath('a/text()').extract_first()
idstr=item.xpath('a/@href').extract_first()
idstr=idstr[idstr.find('=')+1:]
if dbhelp.ispropertyexits(idstr):
return
request=scrapy.Request(url='http://ris.szpl.gov.cn/bol/projectdetail.aspx?id='+idstr, method='GET',callback=self.showdetailpage)
yield request
'''以下是分页代码,组合post_data结构体,
POST请求要使用 yield scrapy.FormRequest(url=response.url,formdata =post_data,callback=self.parse,dont_filter=True)函数。
'''
next_page = response.xpath('//*[@id="AspNetPager1"]/div[2]/a[3]/@href')
pnum=next_page.extract_first().split(',')[1].replace("'","").replace(")","")
post_data = {
"__EVENTTARGET" : "AspNetPager1",
"__EVENTARGUMENT" :pnum,
"__VIEWSTATEENCRYPTED" : "",
"tep_name" : "",
"organ_name" : "",
"site_address" : "",
"AspNetPager1_input" : "1"}
a = response.xpath('//*[@id="__VIEWSTATE"]/@value')
post_data['__VIEWSTATE']=a.extract_first()
b=response.xpath('//*[@id="__VIEWSTATEGENERATOR"]/@value')
post_data['__VIEWSTATEGENERATOR']=b.extract_first()
c = response.xpath('//*[@id="__EVENTVALIDATION"]/@value')
post_data['__EVENTVALIDATION'] = c.extract_first()
'''分页到最后一页,‘下一页’的按钮就不是链接了,页面没有href参数了,此时判断分页结束,即 递归结束'''
if pnum is not None and pnum!="":
yield scrapy.FormRequest(url=response.url,formdata =post_data,callback=self.parse,dont_filter=True)
二、如何在请求和响应之间传递参数
有时需要将两个页面的内容合并为一项。这时候就需要在产生scrapy.Request的同时传递一些参数到下一页。此时您可以执行此操作。
request=scrapy.Request(houseurl,method='GET',callback=self.showhousedetail)
request.meta['biid']=biid
yield request
def showhousedetail(self,response):
house=HouseItem()
house['bulidingid']=response.meta['biid']
三、管道区分传入的Item
每个页面都会封装item并传递给管道进行处理,管道只接收一个条目:
def process_item(self, item, spider)函数
用于区分项目的方法。
def process_item(self, item, spider):
if str(type(item))=="":
self.saverishome(item)
if str(type(item))=="":
self.savebuliding(item)
if str(type(item))=="":
self.savehouse(item)
return item # 必须实现返回