《搜索引擎零距离》第二章 IRS(4)
roki
2009-06-18
3.2.16 爬虫配置语句
爬虫配置语句是一个集中配置与爬虫相关的配置选项的语句,供3.2.3节中的“爬虫配置声明语句”来引用。 示例: ------------------------------------------------------------------- 爬虫配置: 名称=conf1,编码=UTF-8,最大线程数=3 ,抓取延迟=1000,输出=数据库 . ------------------------------------------------------------------- 上述配置中各个字段的意义说明如下。 名称:本爬虫配置的命名,供“爬虫配置声明语句”引用。 编码:默认的用来解析页面的编码。 最大线程数:最多同时运行的爬虫任务数。 抓取延迟:每次访问一个页面之后,爬虫的暂停时间。 输出:执行保存语句之后的目标存储位置,默认是输出到控制台。 爬虫配置语句的格式是: 爬虫配置:key1=value1, …,keyN=valueN. 以“:开头”,“.结尾”,用“=”分隔键和值,用,分隔多个键值对。 3.2.17 系统配置语句 系统配置语句是针对IRS虚拟机的配置,比如爬虫发送HTTP请求时所使用的代理服务器地址。系统配置的文本内容是一个单引号包围的字符串。 示例: ----------------------------------------------------------- 系统配置 '代理服务器= myproxy.com:8080 otherKey=otherValue' ----------------------------------------------------------- 系统配置语句的格式是: 系统配置 ' key1=value1 … keyN=valueN ' 以单引号开头和结尾,用“=”分隔键和值,用换行分隔多个键值对。 3.2.18 外部配置文件 对于某些比较复杂的配置,IRS脚本内部的简单配置格式就无法表达了,因此引入了外部配置文件的概念。 IRS的外部配置文件的一个示例如sampeConf.xml所示: <?xml version="1.0" encoding="GBK"?> <configuration> <!--某个站点同时并发请求数配置--> <maxSiteLink> <site domain="bookwap.net" link="2"/> <site domain="wap.uucun.com" link="4"/> </maxSiteLink> <!--代理列表配置--> <proxylist> </proxylist> <irs> <pages> <!--处理某个页面时,使用哪个http配置--> <page name="resumepage" http="listHttp"/> <page name="crawlerGui" http="otherHttp"/> </pages> <!--配置一个httphead,以供下面的http配置引用--> <head name="rootHead"> <item key="Referer" value="http://www.sc.sh.cn/ "/> <item key="User-Agent" value="Mozilla/4.0"/> <item key="Cookie" value="SESSIONI=KHOAB"/> </head> <!--配置一个http,以供page配置引用引用, 它的head属性引用上文中定义的head节点--> <http name="listHttp" method="POST" head="rootHead"> <body> <![CDATA[sex=0&age_down=&age_up=&city=0°ree_id=0&d_way=0&computer_level=0&foreign1=0&foreign1_extent=0&function_big=11&function_small=&keyword=]]> </body> <Content-Type>application/x-www-form-urlencoded</Content-Type> </http> <!--配置一个另一个http,以供名为"CrawlGui"的page配置引用--> <http name="otherHttp" method="POST" head="rootHead"> <body> <![CDATA[sex=0&age_down=&age_up=&city=0°ree_id=0&d_way=0&computer_level=0&foreign1=0&foreign1_extent=0&function_big=11&function_small=&keyword=]]> </body> <Content-Type>application/x-www-form-urlencoded</Content-Type> </http> </irs> </configuration> 通过上面这个外部配置文件,我们可以更精确的定义智能爬虫的行为,从而可以满足各种HTTP访问方式的苛刻要求。为了使得某个IRS脚本能够使用这个配置文件,需要在脚本中加上一句:系统配置 '外部配置文件=sampleConf.xml'。 3.2.19 执行语句块 执行语句块里表述了爬虫如何读取页面配置来开始信息采集任务。 示例: ------------------------------------------------- 执行 抓取 页面名 '灯火书城' ; ------------------------------------------------- 上述语句的意义是,执行名叫“灯火书城”的页面配置所定义的抓取任务。执行语句块的格式是: 执行 抓取 页面名 'page1' 抓取 页面名 'page2' …. 抓取 页面名 'pageN' ; 语句从“执行”开始, 以一个分号(;)结束。 3.2.20 IRQL存储语句 IRQL存储语句的设计目的是为了处理数据。为了把爬虫系统在遍历各种网页的过程中收集到的各种数据(树状的、层次的、复杂的结构化数据)整理、提取成适合通用的关系型数据库(比如Oracle)能够存储的格式,需要一种表达力比较强的数据描述语言,因此笔者仿造SQL设计了这种IRQL(Information Retrival Query Language)语言,并用一个Java语言编写的小型数据库引擎提供了对IRQL语言的支持。 一个IRQL语句由5部分组成:特殊处理语句、页面别名声明语句、字段选择语句、结果过滤条件和存储对象语句。 IRQL示例: 'href->contentLink,更多小说页->小说入口.href->detailLink; 17K手机入口页:P1, 更多小说页:P2, 更多.详细信息页:P3; select P1->cateName,P2->bookName,P2->author,P2-> detailLink,P3.status,P3.brief,P3.contentLink; novelDao->insert("srcSite"="风雨书城")' 上述IRQL由4段组成,由3个;分隔开。语法格式: IRQL='特殊处理语句;页面别名声明语句;字段选择语句;存储对象语句' 1. 特殊处理语句 特殊处理语句的作用是对结果集做一些额外的处理,多个特殊处理语句之间用逗号分隔。 2. 多表融合语句 存在这样一种比较复杂的场景:某页面上,需要执行两种匹配,title和describe,因此需要写两个IEE表达式,比如: ------------------------------------------------------- 匹配:'title1' '<title>[$title]<title>' 匹配:'describe1' '描述:[$describe]<br/>' ------------------------------------------------------- 但是,由于目标页面有两种模板,也就是说,有时候title和describe需要用以下IEE获取: ------------------------------------------------------- 匹配:'title2' '<H>[$title]</H>' 匹配:'describe2 '简介:[$describe]<br/>' ------------------------------------------------------- 综合以上情况,最后的IRS的主要语句片段的写法是: ------------------------------------------------------- 页面配置 页面名 '结果页' 匹配:'title1' '<title>[$title]<title>' 'NULL' 匹配:'describe1' '描述:[$describe]<br/>' 'NULL' 匹配:'title2' '<H>[$title]</H>' 'NULL' 匹配:'describe2' '简介:[$describe]<br/>' 'NULL' 保存:'savetb' ' merge(结果页->title1结果页-> describe1结果页->title2 结果页-> describe2)=>结果页->newtb; 结果页-> newtb:P; select P.title,P.describe; dao->insert(); ' Ruby: ' #在IEE'title1'匹配失败的情况下,尝试'title2' if(!vm.match('title1')) vm.match('title2'); end #在IEE'describe1'匹配失败的情况下,尝试'describe2' if(!vm.match('describe1)) vm.match('describe2); end #执行保存语句'savetb' vm.save('savetb'); ' ------------------------------------------------------- 以上IRS片段中关键的是这句: merge(结果页->title1结果页-> describe1结果页->title2 结果页-> describe2)=>结果页->newtb; 这个特殊处理语句的功能是把4张表中匹配到的数据融合到一起,上述4个表的名称“结果页->title1 结果页-> describe1 结果页->title2 结果页-> describe2”用空格或换行符分开,=>符号后面跟上融合后的表的名称“结果页->newtb”,然后就可以在页面别名语句中用“结果页->newtb:P”来声明页面别名了,最后就可以使用字段选择语句select P.title,P.describe来获得如表3.4所示形式的数据。 表3.4 结果页->newtb
这个表实际上是以下4张表融合的结果,我们分析一下各种可能出现的情况。 情况1:在IEE title1和describe1匹配成功的情况下,4个表的内容如表3.5和表3.6所示。 表3.5 结果页->title1
表3.6 结果页->describe1
而结果页->title2和结果页->describe2都是空表,这4个表融合成第一条记录SampleTitle1,SampleDescribe1。 情况2:在IEEtitle2和describe2匹配成功的情况下,4个表的内容如表3.7和表3.8所示。 表3.7 结果页->title2
表3.8 结果页->describe2
而结果页->title1和结果页->describe1都是空表,这4个表融合成第二条记录SampleTitle2,SampleDescribe2。同样,如果title1和describe2匹配成功,或者title2和describe1匹配成功,都可以用类似的逻辑获得完整的数据。 多表融合语句为结果集的处理提供了更强大灵活的功能。 3. 额外字段语句 额外字段语句的作用是在结果集合里加入一些额外的特殊字段,举例说明。页面内容: ----------------------------------------------- '<a href="/book/url1.jsp?id=1">book1</a><br/>' '<a href="/book/url2.jsp?id=2">book2</a><br/>' '<a href="/book/url3. jsp?id=3">book3</a><br/>' ----------------------------------------------- 模式匹配语句: ----------------------------------------------- 页面配置: 页面名 '小说列表页' 匹配:'book''<a href="[$]?id=[$id]">[$bookName]</a><br/>'; ----------------------------------------------- 用以上模式匹配语句可以从正文中提取获得如表3.9所示的数据。 表3.9 提取的数据
但是如果这个时候,我们想把 "/book/url1.jsp?id=1"这个URL存入某个字段,就没法在“模式匹配语句”里表达出来了,为了解决这个问题,可以把这个需求表达在IRQL的特殊处理语句里。可以这样写:小说列表页->book.href=>detailBookLink。其中,上述特殊语句又是由4个部分组成的:页面名->匹配名.href=>字段名。此特殊语句的含义是:把“小说列表页”这个页面上的book这个语句匹配到的文本内容中的URL保存为detailBookLink这个字段名。如果这个页面上的IRQL语句中有以上这个特殊处理语句,则最终的数据集合如表3.10所示。这样就得到了我们需要的各个结构化数据字段的值。 表3.10 数据集合
4. 页面别名声明语句 页面别名声明语句的作用是简化IRQL语句,把一个比较长的页面名或者匹配名用一个短小的单词代替,以便在以后的字段选择语句中的引用。 示例: 小说类列表页:P1, 详细信息页->bool:P2; 页面别名声明语句的格式是: 页面名||页面名->匹配名: 别名, 页面名2||页面名2->匹配名2: 别2…, 页面名N||页面名N->匹配名N: 别名N; 各个别名声明之间用“,”隔开,整个语句用“;”结束。 另外,可以用${parentPage}:P来表示当前页面的父页面,以及用${parentPage*2}:P来表示二级的父页面,依次类推,用${parentPage*N}:P表示N级父页面,具体含义将在本章最后的实例中更详细描述。 5. 字段选择语句 “字段选择语句”具有和SQL相似的格式,这个语句中指明了需要保存的字段信息,以及需要进行的额外处理。 示例: select P1->cateName,P2->bookName,P2->author,P3.status,P3.brief bookBrief where P2->author!='匿名' and bookBrief is not NULL ; 以上语句的前半部分为select子句,用来描述结果数据集中所需的字段,后半部分为where子句,对于select子句获得的数据集合,可以用where子句进行过滤,去掉不符合条件的记录,这和SQL语言中的用法是完全一样的。 在解释以上语句之前,需要对爬虫遍历页面过程中获得的各种数据的结构进行说明。爬虫获得的数据是有层次性的,有3种不同层次类型的数据表,分别命名为共享表、独立表和继承表。 下一节中将具体阐述“共享表、继承表和独立表”这3种概念的意义与区别。 |
相关讨论
相关资源推荐
- tinymce-uploadimage:TinyMCE 4插件以上传图像(base64)
- vue-element-admin-tinymce本地化文件
- tinymce-mathjax:Tinymce MathJax插件
- tinymce-formatpainter-skwang:适用于tinymce的免费formatpainter插件
- ember-tinymce:TinyMCE v5的余烬
- angular-ui-tinymce:具有工作设置功能的 angular-ui tinymce
- tinymce-docs:TinyMCE文档
- 前端项目-angular-ui-tinymce.zip
- tinymce-vue:TinyMCE Vue官方组件
- emojidex-tinymce-plugin:适用于tinymce的emojidex插件