scrapy分页抓取网页(一下中代码实现是用C#语言来实现的抓取问题)
优采云 发布时间: 2022-01-28 01:14scrapy分页抓取网页(一下中代码实现是用C#语言来实现的抓取问题)
我相信所有个人网站站长都有抓取别人数据的经历。目前抓取别人的网站数据只有两种方式:
一、使用第三方工具,其中最著名的是优采云采集器,这里不再赘述。
二、自己写程序来抓包,这种方法需要站长自己写程序,可能需要站长的开发能力。
起初,我也尝试使用第三方工具来获取我需要的数据。因为网上流行的第三方工具要么不符合我的要求,要么太复杂,一时间没看懂怎么用,后来决定自己写好了,现在基本可以搞定了网站 半天(只是程序开发时间,不包括数据采集时间)。
经过一段时间的数据爬取生涯,我遇到了很多困难。最常见的一种是分页数据的爬取。原因是数据分页的形式有很多种。下面我主要介绍三种形式。抓取分页数据的方法,虽然在网上看过很多文章,但是每次拿别人的代码,总是会出现各种各样的问题。以下代码都是正确的实现,我目前正在使用。本文中的代码实现是用C#语言实现的。我认为其他语言的原理大致相同。
让我们切入正题:
第一种方式:URL地址收录分页信息。这种形式是最简单的。使用第三方工具爬取这个表单也很简单。基本上,您不需要编写代码。对我来说,我宁愿花半天时间自己写。懒得学第三方工具的人还是可以自己写代码来实现的;
该方法是通过循环生成数据分页的URL地址,如: 这样通过HttpWebRequest访问对应的URL地址,返回对应页面的html文本。接下来的任务是解析字符串并将需要的内容保存到本地数据库;抓取的代码可以参考以下:
publicstringGetResponseString(stringurl)
{
string_StrResponse="";
HttpWebRequest_WebRequest=(HttpWebRequest)WebRequest.Create(url);
_WebRequest.UserAgent="MOZILLA/4.0(兼容;MSIE7.0;WINDOWSNT5.2;.NETCLR1.1.4322;.NETCLR2.0.50727;.NETCLR3.0.04506.648;.NETCLR3.5.21022;.NETCLR3.@ >0.4506.2152;.NETCLR3.5.30729)";
_WebRequest.Method="GET";
WebResponse_WebResponse=_WebRequest.GetResponse();
StreamReader_ResponseStream=newStreamReader(_WebResponse.GetResponseStream(),System.Text.Encoding.GetEncoding("gb2312"));
_StrResponse=_ResponseStream.ReadToEnd();
_WebResponse.Close();
_ResponseStream.Close();
return_StrResponse;
}
上面的代码可以返回对应页面的html内容的字符串,剩下的工作就是从这个字符串中获取你关心的信息。
第二种方式:可能通过网站的开发遇到,它的分页控件通过post的方式将分页信息提交给后台代码,比如.net下Gridview自带的分页功能,点击页码的时候的分页,你会发现URL地址没有变,但是页码变了,页面内容也变了。仔细看会发现,当你把鼠标移到每个页码上的时候,状态栏会显示 javascript:__dopostback("gridview","page1") 等等,这个表格其实也不是很难,因为经过所有,有一个地方可以得到页码的规则。
我们知道提交http请求有两种方式:一种是get,另一种是post,第一种是get,第二种是post。具体提交原理无需赘述,不是本文重点
爬取这类页面需要注意页面的几个重要元素
一、__VIEWSTATE,这应该是 .net 独有的,也是 .net 开发人员又爱又恨的东西。当你打开一个网站的页面时,如果你发现了这个东西,并且后面跟着很多乱七八糟的字符,那么这个网站一定要写;
二、__dopostback 方法,这是一个页面自动生成的javascript方法,包括两个参数,__EVENTTARGET,__EVENTARGUMENT,这两个参数可以参考页码对应的内容,因为点击翻页的时候,页码信息将传递给这两个参数。
三、__EVENTVALIDATION 也应该是独一无二的
不需要太在意这三样东西是干什么的,只要在自己写代码抓取页面的时候记得提交这三个元素就可以了。
和第一种方法一样,_dopostback的两个参数必须通过循环拼凑,只有收录页码信息的参数需要拼凑。这里有一点需要注意,就是每次通过Post提交下一页请求时,首先要获取当前页的__VIEWSTATE信息和__EVENTVALIDATION信息,这样第一页的分页数据就可以可以通过第一种方法获得。然后同时取出对应的__VIEWSTATE信息和__EVENTVALIDATION信息,然后循环处理下一页,每爬完一页后,记录__VIEWSTATE信息和__EVENTVALIDATION信息,提交给下一页post数据使用
参考代码如下:
for(inti=0;i