自动登录抓取功能使用方法

自动登录抓取网页有两种情景:

  • DataScraper正在抓取某个网页,但是遇到了登录页面,登录后能够自动跳转回原页面进行抓取。自动登录所需参数放在周期性调度文件的名字为crawl的步骤(step),也就是说,抓取某个网页时根据需要进行登录。比如,抓取新浪微博,抓取一段时间后,新浪微博可能要求进行登录。
  • DataScraper采用预先登录方式,在抓取网页前先登录这个网站,然后再抓取网页。那么需要在周期性调度文件中增加一个名字为login步骤(step)。该step应该放在名字为crawl的step之前。

所有自动登录抓取情景仅对周期性自动抓取有效,手工启动的网页抓取不能使用自动登录。如果手工抓取网页,那么可以先在火狐浏览器上登录目标网站,紧接着运行DataScraper,就能利用火狐上的登录状态。

注意:自动登录功能是MetaSeeker企业版特有的,在线版不支持自动登录。



自动登录抓取网页的原理

原理很简单,只需要告诉DataScraper登录目标网站所需的登录网页、登录帐号和密码,通过配置周期性调度文件即可告诉DataScraper这些需要的信息。需要的信息有:

  • loginpage:登录网站的网页。有些网站有单独的用于登录的网页,比如,CSDN网就有一个专门的登录网页http://passport.csdn.net/account/login ,但是,更多的网站,在其首页上就有输入帐号和密码的会员登录区,比如,百度空间中国机电出口指南。无论哪种方式,凡是有登录区的网页都可以作为loginpage。
  • loginaccount:登录帐号
  • loginpassword:登录密码
  • accountinput:输入登录帐号的HTML INPUT的XPath表达式。这个表达式需要查看HTML页面源代码后自己编写,或者用MetaStudio的DOM查看器生成XPath表达式。注意:MetaStudio的DOM查看器生成的XPath表达式是一个绝对表达式,即从HTML的顶层节点html开始,到这个节点包含所有HTML标签的完整的XPath表达式。实际上可以用一个相对表达式,因为输入帐号的INPUT一般会有个属性@name,通常还有其他属性,比如@class, @id,假设@name='username',那么,相对的XPath表达式可能就是//*[@name='username']。用相对表达式,更能适应网页结构的变化。另外需要注意,如果登录区在frame/iframe中,DataScraper仍然可以处理,需要在accountinput表达式中描述frame/iframe的位置,用<context>标签表示frame/iframe的位置。如果frame/iframe嵌套多层,那么需要多个<context>标签,这样,整个accountinput变成了 input_xpath<context>内层frame_xpath</context><context>外层frame_xpath</context>
  • passwordinput:输入密码的HTML INPUT的XPath表达式。编写方法同accountinput。
  • submitinput:提交登录的按钮或者图标的XPath表达式,当前,很多网站用Javascript实现网页动作,所以,提交按钮可能不是一个INPUT,而是一个图标,DataScraper可以像处理普通网页那样处理AJAX处理过程。编写方法同accountinput。
  • loginmark:执行自动登录后,是否成功了,需要检查网页上的特征标志,比如,大部分网站会在网页顶端显示:欢迎xxx。这就是特征标志,也需要一个XPath表达式,同accountinput, passwordinput, submitinput 一样。
  • loadPageDelay:(仅适用于情景2)加载了登录页后,要等待多长时间才开始自动录入账号和口令,很多网站,比如,新浪微博,需要等待比较长的时间,这个参数以秒为单位

还有一些辅助参数,参看周期性调度文件

对于第一种情形,不需要配置登录网页,DataScraper像往常一样进行网页抓取,如果发现网页上有登录区,则进行登录。对于第二种情况,总是在抓取网页前进行登录,通常是在抓取一批数据之前进行一次登录,尤其是对周期性增量抓取有用,比如,每过一天抓取一批新增的网页内容,那么在这次抓取之前先进行一次登录。



情形1的crontab.xml样例

抓取某页时,如果遇到需要登录的页面,则登录,crontab.xml片断如下:

   <thread name="weibo_list">
       <parameter>
           <auto>true</auto>
           <start>60</start>
           <period>60</period>
           <waitOnload>false</waitOnload>
           <minIdle>4</minIdle>
           <maxIdle>5</maxIdle>
       </parameter>
   
       <step name="crawl">
           <theme>weibo_sina_list</theme>
           <loadTimeout>120000</loadTimeout>
           <updateClue>true</updateClue>
           <dupRatio>80</dupRatio>
           <stopOnVoid>true</stopOnVoid>
           <depth>2</depth>
           <width>5</width>
   
           <loginaccount>xxx帐号</loginaccount>
           <loginpassword>xxx密码</loginpassword>
           <accountinput>//div[@class='W_login_form']/div/div/input[@name='username']</accountinput>
           <passwordinput>//div[@class='W_login_form']/div/div/input[@name='password']</passwordinput>
           <submitinput>//div[contains(@class,'login_btn')]/div/a[@class='W_btn_g']</submitinput>
           <loginmark>//div[contains(@class, 'header')]/div[contains(@class, 'person')]/div[contains(@class, 'setting')]/a[contains(@class, 'name')]</loginmark>
   
           <renew>false</renew>
           <period>0</period>
           <allowPlugin>false</allowPlugin>
           <allowImage>false</allowImage>
           <allowJavascript>true</allowJavascript>
       </step>
   </thread>


情形2的crontab.xml样例

在线程的开头,增加一个专门登录的步骤,参看如下crontab.xml片断

   <thread name="weibo_list">
       <parameter>
           <auto>true</auto>
           <start>60</start>
           <period>60</period>
           <waitOnload>false</waitOnload>
           <minIdle>4</minIdle>
           <maxIdle>5</maxIdle>
       </parameter>
   
       <step name="login">
           <theme>weibo_sina_list</theme>
           <timerTriggered>false</timerTriggered>
           <lazyCycle>3</lazyCycle>
           <loginpage>http://weibo.com/</loginpage>
           <loginaccount>xxxx帐号</loginaccount>
           <loginpassword>xxx密码</loginpassword>
           <accountinput>//div[@class='W_login_form']/div/div/input[@name='username']</accountinput>
           <passwordinput>//div[@class='W_login_form']/div/div/input[@name='password']</passwordinput>
           <submitinput>//div[contains(@class,'login_btn')]/div/a[@class='W_btn_g']</submitinput>
           <loginmark>//div[contains(@class, 'header')]/div[contains(@class, 'person')]/div[contains(@class, 'setting')]/a[contains(@class, 'name')]</loginmark>
           <loadTimeout>60000</loadTimeout>
           <loadPageDelay>10000</loadPageDelay>
       </step>
       <step name="crawl">
           <theme>weibo_sina_list</theme>
           ......
       </step>
   </thread>