突破限制爬取网页数据 googlesholar为例【转】

1、为什么要爬取google scholar数据  
     Google Scholar上论文信息较为丰富,可以对应中英文搜索,结果较为完备,通过高级查找能够找到精确的
结果。等等

2、爬取网页的一般设置  
    我们有时候会发现,用浏览器可以查看某个网站的网页,但是当我们用程序去爬取网页时,却得不到结果,
或者说返回错误(如果你没遇到过,那看来你一般爬取的是比较简单的网站的网页)。这是什么原因呢?一
般的http请求,浏览器在执行的时候,并不是像我们看到的那样简单,只是向服务器发送请求某个网页的命
令。在这个过程中,浏览器还会发送一些附加的信息,如“Accept”接收文件爱你的类型,”Accept-
Language”接受语言,”Accept-Charset”接受的编码等。
    在这其中,对于一般爬取网页比较重要的就是“User-Agent”,它代表发出该http请求的客户端,一般包括浏
览器和操作系统的信息。如“User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 
Firefox/3.6”。一般网站为了封堵程序爬取其信息,或是避免影响正常用户的访问,都会检查该项设置。那
我们在程序中对该项进行设置,就可以正常的访问爬取网页了。
    可能有些网页,不仅检查该项,还会同时检查“referer”项信息。Referer记录的是你从那个网页上的链接点
击现在正在查看的网页的。这是因为有时候,网站的某个网页只要求是在其网站内部访问时点击进来的才可
以访问,举个比较常见的例子,有时候你在浏览网页的时候会发现网页上的图片显示错误,“你看的图片来
自…”,”…仅限于站内交流”,俗称“图片盗链”,这就是网站通过查看“referer”信息实现的。
通过设置这两项内容,基本就可以下载一般网站的网页了。

3、Google scholar的特殊之处及应对措施  
     如果只是爬取Google Scholar的搜索结果,并没有什么特殊的地方,直接爬取就行了。但是,因为我需要每
个论文的参考信息(在高级设置里有),即将论文导出成Endnote信息。该选项默认是不显示的,那要进行
怎样的设置才能找到该信息呢?
     要对这个问题进行说明,首先要介绍下网络服务模型的一些东西。首先,分服务器端和客户端,服务器端一
般就是我们所说的网站了,那么你在浏览其网站时,就是一个客户端,更直接点说就是浏览器。当我们做出
一些选择时,怎么让服务器知道呢,怎么把参数传给服务器,一般有post和get两种方式。Get方式是直接
在 链接的后面跟上一些参数,post方式则是在http的请求中,位于请求头内部的。在Google搜索中,我们可以设置一页显示100条结果记录,可以设 置中英文搜索,可以设置从第几条结果返回,等等。这些参数都是通过get方式设定的。但是要让scholar的结果显示“导出Endnote”的链接,需 要事先到一个页面上进行设置,向服务器提交设置。在提交这些设置的过程中,很容易发现它是通过form-get方式传递参数的。但是设定完之后,再次进行 搜索时,并没有在搜索页面的后面增加一个参数,而仍是和原来一样的url。页面中也没有其他的隐藏的post参数。那为什么现在就能显示出来“导出 Endnote”的链接呢?
     Cookie?没错,Google Scholar使用了Cookie来保存你的搜索偏好设置。Cookie是为了维护你在浏览网页时的一些信息设置的,比如在不同的页面间维持登录消息。查 知,分两种session cookie和persistence cookie,一种存在你的硬盘上,一种则是随着窗口的关闭而消失。不管怎样,Google Scholar是把我们搜索的高级选择存到了cookie中,那接下来就是要在你的程序中进行相应的设置。
不同的浏览器是不共享cookie的,网上查询知,在java中可以通过一定的步骤来获取某次http请求的cookie信息(cookie信息是从服务器发送到客户端进行存储的),那我得到cookie信息后,就可以模仿人为访问来爬取页面了。
      不过值得说明的是,在我爬取的过程中,发现设置完cookie后并没有显示想要的链接内容,通过对比浏览器的cookie和我仿造的cookie,发现需 要在得到cookie的基础上进行改进,可是通过多次测试,也没整明白这个额外的信息是从什么时候给添加到浏览器客户端上的。
     比如我模拟opera浏览器的user-agent(在opera浏览器的地址栏中输入 “javascript:alert(navigator.userAgent)”可得),向google scholar的搜索爱好设置项页面发送请求,得到的cookie信息为 “PREF=ID=7d7f54d6ace3ddee:LD=en:NR=100:NW=1:TM=1269084787:LM=1269084787:S=9SzH07PRA1xd7rwh; GSP=ID=7d7f54d6ace3ddee”。简单说明下,分号前面的据我推测应该是搜索偏好的搜索设置信息,后面的就是你的cookie id信息了。利用这个cookie进行请求时,并没能如我所愿的看到“导出为Endnote”的链接,这是为什么呢?现在拿这个cookie对比浏览器中 进行过相应设置的cookie,如 PREF=ID=3091859a4fd2f136:U=4927399a4c6ef959:LD=en:NR=100:NW=1:CR=2:TM=1268316933:LM=1268987338:GM=1:S=gxL2FV6kIdXGARMD;NID=32=GYLdF8rZWqUo82gx_Pop-eaiDGHpDa7-d6g3n-d66c1UVWNEFiD99ERd9T-0izVjmI4-u5SzsU2bIFjbCjGTV7poV22bpNWbKIOHYsIv4pDnHO2BbsFKRmg7DvIJPmCE; 
GSP=ID=3091859a4fd2f136:IN=8b9a455bd1c58d67:CF=3 ;S=sorry=ZKTU9UFyzml7PNQcOySXww;GDSESS=ID=3091859a4fd2f136:EX=1269100800:S=9vcgIt1YDAWR9C_P;SID=DQAAAIkAAACaSIE2V1fT5KDklGwKUutN-3eiGuOTGfQFGxtm_pWhRDUmx-hG6FOhht4eVM5MHbiyZpyB_h3UwONT8SZrw08fqu_36vfh9kTUvCR1g4UU3aGWx9k1lQTDvQEgbhIOIJ3QFfxdVACSEI22Oz-3tVydfrqDOjK-PUuuzPwNRMkMHlCgGI7nKInKjHrIIO0VuI; HSID=Akp34ZX0kDvONGUMm
   刚刚得到的cookie,信息比较多,可能是保存了我进行过过多请求的原因。不过无所谓,注意红色部分,多了一个CF=3,在我仿的cookie上加该信息即可得到想要的内容了。

4、 针对高技术网站反爬的对策  
    你能想的到的,那帮天才们当让也会想的到。即使模仿了cookie,也是有办法阻止你的爬取的。其实我现在
也 不知道需不需要费心的去模拟浏览器得到一个新的cookie,因为我们已经能够通过工具看到浏览器在进行请求时的cookie了,直接用它不就完了吗?之 所以这样做,一部分原因是怕google会进行用户行为的记录,而如果它把我的账户与当前cookie关联起来,以后如果遇到一些问题岂不麻烦。也许杞人 忧天了。开始爬取时,我用的就是浏览器里看到的cookie信息,结果进行一次搜索后,就被google发现而禁止了,就是弹出“sorry。。。。”然 后好一点给你个机会让你输下数字等,证明你是human,不好的话就是你只能等待一段时间再进行搜索了。当然,这样不行啊。短时间进行大量访问请求,很容 易被网站发现封掉。那我们可以一次请求后等待一段时间。有些网站会观察你一段时间的请求,看你是不是在十分精确地间隔一段时间发一次请求。因为人是不会这 样的,你查看一个链接的间隔是很不规则的。既然有人提出了,不管google有没有做,那我就按照通常的做法,进行一次请求,随机的等待一段时间,更 human些。为了避免被封掉,我把等待间隔设置的很长。每几十秒进行一次请求,因为相信只要有愚公移山的精神,总能够完成页面的爬取,何况程序整天工作 也不会觉得累。
      还是怕会被封掉,因为是在实验室进行的,如果我的被封掉,那整个实验室都不能再进行访问了,后果有点严重。能不能避免呢?代理。通过中间代理进行访问,那即使封也不会封到实验室的ip了。而且,你还可以通过多个代理同时进行访问,加快速度。

5、用到的工具说明 
    请求网页和设置cookie等,都是通过java urlconnection完成的
    搜索得到的结果,在提取所用信息时,通过html parser来做
    如何查看浏览器的发送请求和响应信息呢,十分推荐firebug,是firefox浏览器的一个插件,如果你经常和网页打交道,它是很有用的。用它,就可以看到浏览器中的cookie信息。

6、程序 
代理设置例:  
            System.getProperties().put("proxySet", "true");
            System.getProperties().put("proxyHost", host);
            System.getProperties().put("proxyPort", port);
请求信息设置例:  
            URL url = new URL(pageURL);
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            con.setConnectTimeout(500000);
            con.setReadTimeout(1000000);
            con.setRequestProperty("User-Agent", "Opera/9.27 (Windows NT 5.2; U; zh-cn)");
                 con.setRequestProperty("Cookie","PREF=ID=7d7f54d6ace3ddee:LD=en:NR=100:NW=1:TM=1269084787:LM=1269084787:S=9SzH07P
RA1xd7rwh;GSP=ID=7d7f54d6ace3ddee:CF=3");
            con.connect();
得到cookie:  
        public void getCookies(URLConnection con){
        Map<String,String> cookie = new HashMap<String,String>();
        String headerName = null;
        for(int i=1;(headerName = con.getHeaderFieldKey(i))!=null;i++){
            System.out.println(headerName+":"+con.getHeaderField(i));
            if(headerName.equalsIgnoreCase("Set-Cookie")){
                StringTokenizer st = new StringTokenizer(con.getHeaderField(i),";");               
                if(st.hasMoreElements()){
                    //System.out.println("here");
                    String token = st.nextToken();
                    String name = token.substring(0,token.indexOf('='));
                    String value = token.substring(token.indexOf('=')+1);
                    cookie.put(name, value);
                }
            }
        }
        System.out.println(cookie.toString());
    }
7、    慎重爬取网站数据  

author:wendell
mail:wcw19861217@163.com

If you have any question, please send email to me!


转自 : http://www.csdn123.com/html/mycsdn20140110/c3/c38ea63da6df208aa413d29a097ea28b.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值