前面介绍了zengl脚本的基础语法,现在看下如何使用zengl来进行采集,这里以规则较简单的资讯模块为例,将Module目录中的“资讯模块规则.zl”做个备份,然后新建一个"资讯模块规...

    前面介绍了zengl脚本的基础语法,现在看下如何使用zengl来进行采集,这里以规则较简单的资讯模块为例,将Module目录中的“资讯模块规则.zl”做个备份,然后新建一个"资讯模块规则.zl",并在其中输入如下代码:

use builtin;
def TRUE 1;
def FALSE 0;
def NORMAL 0;
def RED 1;
def GREEN 2;

Max_CaijiNum = bltGetCaijiNum(); //获取每个分类最多采集条数。
catid = bltGetCatid(); //获取当前采集分类的分类ID
modid = bltGetModid(); //获取当前采集分类所属的模块ID
catname = bltGetCatName(); //获取当前采集的分类名
caiji_url = bltGetWebUrl(); //获取当前你要采集到的目标网站网址。
caiji_postfileName = bltGetInitManageUrl(); //获取采集的上传接口文件名

print '您设置的单个分类最多采集量为:' + Max_CaijiNum;
print '您当前采集的分类ID为:' + catid;
print '您当前采集分类所属的模块ID为:' + modid;
print '您当前采集的分类名为:' + catname;
print '您当前要采集到的目标网站网址为:' + caiji_url;
print '您在服务端的PHP采集接口文件名为:' + caiji_postfileName;

    上面的代码先获取采集时需要的基本信息,如每个分类最多采集多少条数据,这个在采集开始之前可以在第二排工具栏第一个输入框中进行输入,通过bltGetCaijiNum内建函数可以获取到这个值。分类ID和模块ID为当前要进行采集的分类的信息,这些信息都是在获取网站分类信息时从服务端获取下来的,通过bltGetCatidbltGetModid这两个内建函数就可以获取到,在上传发布时,需要在POST请求中提供这些参数。bltGetCatName则可以获取当前正在采集的分类名称,分类名在采集时可以用于打印调试信息。bltGetWebUrl可以获取要采集的目标网站的网址即工具栏第一排第一个输入框里的信息,bltGetInitManageUrl即服务端的PHP上传接口文件名,默认为zengl_caiji.php,上面的"资讯模块规则.zl"保存后,点击开始,会得到如下结果:

    下面在此基础上再进一步扩展,在上面的代码基础上添加如下代码:

..........................  //省略N行,和上面代码一样
keywords = array(); //初始化一个数组,并将数组赋值给keywords变量,下面将在这个数组中填充该分类的关键词信息

mustwords = array(); //初始化一个数组,并将数组赋值给mustwords变量,下面将在这个数组中填充该分类的关键词对应的必须包含词。

keywords_count = bltGetKeyWords(keywords,mustwords); //在前面的章节中提到过,bltGetKeyWords该内建函数会读取正在采集的分类的关键词信息,并将关键词填充到keywords数组中,将关键词的必须包含词填充到mustwords中。该函数返回的值为关键词的总个数。

i = 0; //作为下面的数组元素索引

print '关键词['+i+']:'+keywords[i] + '\n必需包含词:'+
            mustwords[i]; //打印出i变量索引的关键词信息。

escape_keyword = bltCurlEncode(keywords[i]); //对关键词进行URL编码,只有经过url编码后的关键词才能获取网页内容,如果如UTF8的网站如51job等,就需要先用bltToUTF8将关键词转为UTF8编码,这个可以参考人才模块规则。

print '转义关键词:' + escape_keyword; //显示出URL编码后的关键词信息。

remote_url = 'http://search.china.alibaba.com/news/news_search.htm?keywords=' + escape_keyword + '&newsTabParam=img&n=y'; //根据URL编码后的关键词信息,得到完整的URL地址。

print '采集分页:' + remote_url; //打印出采集分页信息到日志面板

remote_content = bltCurlGetUrl(remote_url); //根据remote_url采集分页链接地址,通过bltCurlGetUrl函数来抓取该链接对应的网页内容。下面就会从网页内容中提取底部的分页链接和当前页的内容链接。

page_links = array(); //初始化分页链接数组,将要存放采集网站的所有底部分页链接

page_links_pattern = 'a\\s.*?href=(["|\']?)(http://search\\.china\\.alibaba\\.com/news/-[^ "\'>]+\\.html\\?pageSize=\\d+&beginPage=\\d+)\\1'; //阿里巴巴在搜索出关键词的页面的底部分页链接的正则表达式规则。

bltRegexMatches(page_links_pattern,2,remote_content,page_links,1,0); /* 根据分页链接规则获取底部分页的链接,第一个参数是正则表达式,第二个参数是获取正则表达式里的第几个元组,第三个参数是要从该参数对应的内容中通过正则 表达式提取信息,第四个参数是将所有匹配到的信息填充到结果数组中,第五个参数是是否需要对结果数组进行唯一化处理,去除重复的信息,1表示需要,0表示不需要,最后一个参数表示正则表达式中的小数点是否匹配所有符号包括换行符。函数返回值是匹配的结果数组的元素个数*/

pagecount = bltArrayInsertString(page_links,remote_url,0); //将当前页链接也压入分页链接数组中。bltArrayInsertString内建函数第一个参数是要操作的数组,第二个参数是要插入的元素,第三个参数是要将元素插入到的数组位置,0表示插入到数组开头。返回的值是插入操作后新的数组的元素总个数。

for(pageindex = 0 ;pageindex < pagecount ; pageindex++) //pageindex为循环时需要使用的分页链接数组索引。
    print '第'+(pageindex+1)+'页的地址为:'+page_links[pageindex]; //循环打印出捕获到的底部分页链接地址。索引pageindex从0开始,所以需要pageindex+1
endfor

    "资讯模块规则.zl"修改保存后,点击开始,会得到如下结果:

    上面有两个概念,一个是底部的分页链接,如下图:

    上图所示的就是一个阿里巴巴的底部分页链接,分页链接正则表达式即page_links_pattern的值就是用来获取这些分页的链接地址的。想测试正则表达式可以使用采集器工具栏的测试按钮:弹出的对话框里可以进行正则测试:

    当然测试通过的正则表达式,需要进行转义,比如将单引号转义,斜杠进行转义等,这些在对话框的日志底部都自动生成了:

    将转义后的字符串写入到zengl脚本中,就可以作为采集的一个规则了,上面代码给出来的是抓取分页链接的规则,再来看下内容链接,如下:

    每个采集页面里都有10来20个需要采集的信息,如上图的"女装有望成为国际高端品牌 为中国服装增加话语权"之类的,每条信息都有一个链接地址,只有正确的获取到这些链接地址,才能顺着地址爬进去,抓取里面的具体信息内容。 下面看下资讯里抓取分页中内容链接的方法:

..........................  //省略N行,在上面的代码中继续添加下面的代码
content_links = array(); //初始化内容链接数组

pageindex = 1; //pageindex为下面page_links分页链接数组索引,设为1,表示先要抓取第二页的内容链接。如果是0就表示第一页。第一页在上面已经抓取过了,这里就从第二页重新抓取。

remote_content = bltCurlGetUrl(page_links[pageindex]); //抓取当前分页(本例中为第2页)的网页内容。

content_links_pattern = 'a\\s.*?href=(["|\']?)(http://info\\.china\\.alibaba\\.com/news/detail/v\\d+-[^ "\'>]+\\.html)\\1'; /*当前页面中内容的链接规则*/

contentCount = bltRegexMatches(content_links_pattern,2,remote_content,content_links,1,0); /*根据内容链接规则获取内容链接数组*/

print '准备打印出当前第'+(pageindex+1)+'页的内容链接地址';

for(contentIndex = 0 ; contentIndex < contentCount; contentIndex++)
    print '['+ (contentIndex+1)+'] 内容链接地址:' + content_links[contentIndex]; //循环打印出内容链接地址。
endfor
    "资讯模块规则.zl"修改保存后,点击开始,会得到如下结果:

    在得到内容页的链接地址后,就可以做个循环,循环抓取每个内容链接,这里先不做循环,试着抓取第一条信息来看下。

..........................  //省略N行,在上面的代码中继续添加下面的代码

contentIndex = 0; //为下面的content_links内容链接地址数组的索引,设为0,表示准备抓取第一条内容链接

remote_content = bltCurlGetUrl(content_links[contentIndex]); //根据内容链接得到每篇文章的内容

title_pattern = '<title>([^<]+)</title>'; //内容页标题的正则表达式规则

if(bltRegexMatchFirst(title_pattern,1,remote_content,&title,0) >=0) // 匹配标题,bltRegexMatchFirst第一个参数为正则表达式,此处为内容页标题的正则表达式,第二个参数为需要获取的正则表达式元组,第三个 参数是需要匹配的内容,第四个参数是匹配的结果,将正则表达式匹配的结果存放到引用对应的变量中如本例的&title,&是变量的引用符号。最后一个参数是正则表达式中的小数点是否匹配包括换行符在内的所有符号。
    printf(content_links[contentIndex] + '\n该链接标题为:' + title,GREEN); //显示捕获的标题
else
    printf(content_links[contentIndex] + '\n该链接没有匹配到标题',RED); //正则表达式捕获失败,打印错误信息。
endif

   
保存后,点击开始,得到如下结果:

    OK,先到这里,下一节介绍如何对分页链接和内容链接进行双层循环,通过双层循环就可以一个链接一个链接的一页一页的采集下去。休息,休息一下,O(∩_∩)O~

上下篇

下一篇: zengl脚本语法 第五章采集入门篇(二)

上一篇: 智能采集器v1.0.4

相关文章

zengl脚本语法 第六章内建函数枚举

智能采集器 v1.2.2共享版

zengl脚本语法 第二章流程控制篇

智能采集器v1.0.4

智能采集器v1.3.0开源版

智能采集器v1.0.5