网页分页数据抓取三种方式

摘要:
经过一段时间的数据采集,我遇到了很多困难。最常见的问题之一是获取分页数据的问题。原因是有多种形式的分页数据。我将主要介绍以三种形式获取分页数据的方法。虽然我在网上看到了很多这样的文章,但每次我使用别人的代码时,总会出现各种问题。以下代码可以正确执行,我现在正在使用它们。

一、使用第三方工具,其中最著名的是火车头采集器,在此不做介绍。

  二、自己写程序抓取,这种方式要求站长自己写程序,可能对对站长的开发能力有所要求了。

  本人起初也曾试着用第三方的工具抓取我所需要的数据,由于网上的流行的第三方工具不是不符合我的要求,就是过于复杂,我一时没有搞明白怎么用,后来索性决定自己写吧,现在本人基本上半天可以搞定一个网站(只是程序开发时间,不包括数据抓取的时间)。

    经过一段时间的数据抓取生涯,也曾遇到了很多困难,其中最常见的一个就是关于分页数据的抓取问题,原因在于分数据分页的形式有很多种,下面我主要针对三种形式介绍一下抓取分页数据的方法,此类文章虽然在网上见过很多,但每次拿别人的代码总也总是有各种各样的问题,下面各种方式的代码都是能正确执行,并且我目前也正在使用中的。本文中代码实现是用C#语言来实现的,我想其他语言原理大致相同。

下面切入正题:

     第一种方式: URL地址中包含分页信息,这种形式是最简单的,这种形式使用第三方工具抓取也很简单,基本上不用写代码,对于我这种宁可自己花个半天时间写代码也懒得学第三方工具的人,还是通过自己写代码实现了;

    这种方式就是通过循环生成数据分页的URL地址 如: 这样通过HttpWebRequest访问对应URL地址,返回对应页面的html文本,接下来的任务就是对字符串的解析,将需要的内容保存到本地数据库内;抓取的代码可参考下面:

 public string GetResponseString(string url){
            string _StrResponse = "";
            HttpWebRequest _WebRequest = (HttpWebRequest)WebRequest.Create(url);


            _WebRequest.UserAgent = "MOZILLA/4.0 (COMPATIBLE; MSIE 7.0; WINDOWS NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";


            _WebRequest.Method = "GET";


            WebResponse _WebResponse = _WebRequest.GetResponse();


            StreamReader _ResponseStream = new StreamReader(_WebResponse.GetResponseStream(), System.Text.Encoding.GetEncoding("gb2312"));


            _StrResponse = _ResponseStream.ReadToEnd();


            _WebResponse.Close();


            _ResponseStream.Close();


            return _StrResponse;
        }  

上面的代码可以返回对应页面的html内容的字符串,剩下的工作就是从这个字符串中获取自己关心的信息了。


 

     第二种方式: 可能是通过asp.NET开发的网站常会遇到,它的分页控件通过post方式提交分页信息到后台代码,如.net下Gridview自带的分页功能,当你点击分页的页码时,会发现URL地址没有变化,但页码变化了,页面内容也变化,仔细看会发现,把鼠标移到每个页码上的时候状态栏会显示 JavaScript:__dopostback("gridview","page1")等等之类的代码,这种形式其实也不是很难,因为毕竟有地方得到页码的规律可寻。

   我们知道http请求提交的方式有两种一种是get一种是Post,第一种方式是get方式,那么第二种方式就是post方式,具体提交的原理不必细说,不是本文的重点

抓取这种页面 需要注意asp.Net页面的几个重要的元素

   一、 __VIEWSTATE ,这个应该是.net特有的,也是让.net开发人员既爱又恨的东西,当你打开一个网站的某一个页面的时候,如果发现这个东西,而且后面还跟随着一大堆乱七八糟的字符的时候,那这个网站肯定是用asp.net写的了;

   二、__dopostback方法,这个是asp.net页面自动生成一个javascript方法,包含两个参数,__EVENTTARGET,__EVENTARGUMENT,这两个参数可以参看页码对应的内容,因为点击翻页的时候,会将页码信息传给这两个参数。

   三、__EVENTVALIDATION 这个也也应该是asp.net特有的东西

大家也不用 太关心这三个东西都是干什么的,只需要注意自己写代码抓取页面的时候 记得提交这三个元素就可以了。

    和第一种方式一样,肯定要通过循环的方式是去拼凑_dopostback的两个参数,只需要拼其中包含了页码信息的参数即可。这里有一个需要注意的地方,就是在每次通过Post提交请求下一页的时候,先应得到当前页的__VIEWSTATE 信息和__EVENTVALIDATION信息,所以分页数据的第一页可采用第一种方式得到页码内容然后,同时取出对应的__VIEWSTATE 信息和__EVENTVALIDATION信息,然后再做循环处理下一页面,然后每抓取完一个页面,再记录下__VIEWSTATE 信息和__EVENTVALIDATION信息,为下一个页面post提交数据使用

参考代码如下:

 for (int i = 0; i < 1000; i++){
               System.Net.WebClient WebClientObj = new System.Net.WebClient();

                System.Collections.Specialized.NameValueCollection PostVars = new System.Collections.Specialized.NameValueCollection();

                PostVars.Add("__VIEWSTATE", "此处是您需要提前得到的信息 ");

                PostVars.Add("__EVENTVALIDATION", "此处是您需要提前得到的信息 ");

                PostVars.Add("__EVENTTARGET", "此处是__dopostback方法对应的参数 ");

                PostVars.Add("__EVENTARGUMENT",  "此处是__dopostback方法对应的参数 ");

                WebClientObj.Headers.Add("ContentType", "application/x-www-form-urlencoded");

                try

                {
                    byte[] byte1 = WebClientObj.UploadValues(" http://www.xxxx.cn/messagelist.aspx ", "POST", PostVars);

                    string ResponseStr = Encoding.UTF8.GetString(byte1); //得到当前页面对应的html 文本字符串


                    GetPostValue(ResponseStr);//得到当前页面对应的 __VIEWSTATE 等上面需要的信息,为抓取下一页面使用 

                    SaveMessage(ResponseStr);//保存自己关心的内容到数据库中 

                }catch (Exception ex){


                    Console.WriteLine(ex.Message);


                }
            }


      第三种方式: 第三种方式是最麻烦的,也是最恶心的,这种页面在你翻页的过程中没有任何一个地方可以找到页码信息,这种方式费了我很大的力气,后来采用了一个比较狠的办法,用代码模拟手动翻页,这种方式应该可以处理任何形式的翻页数据,原理就是,用代码模拟人工点击翻页链接,用代码一页一页的翻页,然后一页一页的抓取。

   正所谓外行看热闹,内行看门道,很多人可能看到这里就会说用Webbrowser这可控件就可以实现,对,我下面的这种方式就是用WebBrowser的这个控件来实现,其实在.net下这种类似的类应该还有,但我没有去研究过,也希望如果有人有其他的方式,可以回复我,与大家一起分享。

  WebBroser控件可是在自己的程序中内嵌一个浏览器,就像IE,火狐之类的一样,你也可以用他开发自己的浏览器,至于用它开发的浏览器的效果怎么样,我觉得肯定是不如IE和火狐了。呵呵

  我们还是 闲言少叙,切入主题:

    使用WebBroser控件基本上可以实现你在IE中操作网页的任何功能,所以点击翻页按钮当然也是可以的了,那既然可以在WebBroser中可以手动点击翻页按钮,自然我们用程序代码同样可以指使WebBroser自动替我们翻页了。

   其实原理很简单,主要分以下几个步骤:

   第一步,打开你想抓取的页面  比如: http://www.zxskb.com/zr/list_O.html  

   调用webBrowser控件的方法Navigate(" http://www.zxskb.com/zr/list_O.html ");

   此时,你应该在你的WebBrowser控件中看到你的网页信息,和IE中看到的是一样的;

   第二步 ,WebBrowser控件的这个事件DocumentCompleted 很重要,当你访问的页面全部加载完之后,会触发这个事件。所以我们分析页面元素的过程也需要在这个事件内完成

   string _ResponseStr=this.WebBrowser1.Document.Body.OuterHtml;

这句代码可以得到当前打开页面的html元素的内容。

    既然已经得到当前打开页面的html元素的内容了,剩下的工作自然就是解析这个大字符串,得到自己关心的内容,解析字符串的过程,大家应该自己都能写了。

第三步, 重点在这第三步呢,因为要翻页了,接第二步,解析完字符串之后,还是在DocumentCompleted事件中,调用方法

WebBrowser1.Document.GetElementById("页码的id ").InvokeMember("click");

从代码的方法名种大家应该能明白了,那么调用完这个方法,之后WebBrwoser控件内的网页就实现了翻页,和你用手去点翻页按钮是一样的效果。

重点在于,翻页之后,还会触发DocumentCompleted事件,所以进入了第二步,第三步的循环了,所以大家需要注意判断跳出循环的时机。

其实用WebBrowser还能干很多事情,比如自动登录,注销某个论坛,保存session, cockie,所以 这个控件基本上可以实现你想对网页的任何操作,哪怕你是想暴利破解一个网站的登录密码,当然这个是不提倡的了。呵呵

转自:http://blog.csdn.net/haoxiang110/article/details/53205850

免责声明:文章转载自《网页分页数据抓取三种方式》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux使用touch批量修改文件/文件夹时间戳tr标签使用hover的box-shadow效果不生效下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

js判断浏览器类型

js判断浏览器类型 <script type="text/javascript" ><!-- function getOs() { var OsObject = ""; if(isIE = navigator.userAgent.indexOf("MSIE")!=-1) { return "MSIE"; } if(isFirefox=na...

操作系统开发:启用内存分页机制

该系列文章是在学习《操作系统真相还原》时通过阅读后简化并适当描述整理的学习笔记,首先,致敬作者郑刚博士,在读本书时能深刻的感觉到作者写书时一丝不苟的态度,书很厚写的,讲解细致幽默,很能让人愿意继续读下去,同时也不得不佩服作者计算机底层功力的深厚。 本文章只是学习笔记,并非原创作品,你可以任意转载,请保留原作者(郑刚)版权信息。 目前我们已进入保护模式,但依...

ASP.NET MVC 3.0(十六): MVC 3.0 实例系列之表格数据的分页

ASP.NET MVC 3.0(一): MVC 3.0 的新特性 摘要 ASP.NET MVC 3.0(二): MVC的概念及MVC 3.0开发环境 ASP.NET MVC 3.0(三): 初识MVC的Url映射潜规则Routing ASP.NET MVC 3.0(四): 我要MVC潜规则之配置Routing ASP.NET MVC 3.0(五): 入手C...

自适应网站设计对百度友好的关键:添加applicable-device标签(转)

现在很多网站都使用了自适应网页设计(Response-Web-Design),以满足庞大的移动端用户群的需要。但是在技术上设计了自适应的网页之后,出于SEO的考虑,你还要照顾到如何对百度更友好,即告诉百度“我是自适应页面”,方便百度进行识别校验。 自适应网页设计 浏览器对自适应识别校验代码 在自适应网页设计中,我们使用meta标签来告诉浏览器网页的自适应...

网页自动登录,自动填充表单代码

实现自动登录某网站,并且登录完成后跳转到指定的页面。然后进行表单的自动填充表单提交 。类型于小型的发帖机 哈哈 (看官在看下面代码的时候,把记得把下面的链接改下) public partial class Form1 : Form { public Form1() { Initializ...

把网页发送到桌面代码

把网页发送到桌面相信很多站长都会用到,可有的站长可能不会写,今天碎碎就给大家分享下把网页发送到桌面php和asp良种语言的代码。   首先我们先做准备工作,要先上传自己网站的ioc文件,这样发送到桌面的时候才会有图标显示。   然后新建一个以shorturl命名的php文件把下面的代码放上去 <?php $Shortcut = "[InternetS...