自动登录抓取网页有两种情景:
- 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>