用Goutte爬虫整合进php项目(ProcessWire)的思路

记录一下用Goutte整合到ProcessWire项目的过程:

建立一个Page存放已经抓取过的URL

每次对URL产生Request前先看看这个页面是不是已经爬过了,然后再做相应更新或者跳过的处理,虽然Goutte不能像binux大神的pyspider以服务形态工作,但是也可以通过人工重复运行爬虫项目更新,或者使用crontab去执行定时任务,这里不做过多说明。

建立一个Page存放并运行Goutte爬虫项目

该Page下存储各个Spider项目,结构应该是这样子的:

Spiders:
----a.com
--------entry1
--------entryN
----B.com
--------entry1
--------entryN

通用爬虫规则

应付简单的内容抓取,为爬虫添加规则配置字段,前面已经说过如何用json存储配置信息,配置内容:

	"bikes":{    //项目中的列表页/频道,可能同一个站点爬去不同的列表
		"url":"http://www.***.com/cn/zh_CN/%E8%87%AA%E8%A1%8C%E8%BD%A6/c/B100/",    //URL
		"pagination":"Next",    //下一页
		"content":{    //内容提取页配置
			"link":".product-tile__button",    //列表页中对内容页的链接提取
			"title": ".buying-zone__title",    //内容字段,标题 
			"images": {     //图片提取,提取内容中独立的图片项目/相册等
                  "item" => ".pdp-thumbnails_item data-zoom-src",    //图片的CSSSelector
                  "src" => "src"    //有些情况下原始图片特别是使用了放大镜插件的时候,并不是src而是zoom-src等
                  },
			"content": "main"    //正文的提取
		},
	}, 
	"components", {
		"url":"http://www.***.com/cn/zh_CN/%E8%A3%85%E5%A4%87/%E8%87%AA%E8%A1%8C%E8%BD%A6%E9%83%A8%E4%BB%B6/c/E200/",
		"pagination":"Next",
		"content":{
			"link":".product-tile__button",
			"title": ".buying-zone__title",
			"images": { 
                  "item" => ".pdp-thumbnails_item data-zoom-src",
                  "src" => "src" 
                  },
			"content": "main"
		},		
	}

有了通用的规则之后每次只需要添加spider的页面并修改相应规则就能应付绝大大部分情况了。

特殊情况的处理

规则已经不管用的时候独立编写规则,spider项目读取配置前先看看独立的spider项目文件在不在,如果在就直接运行该项目,这么一来你就可以抓取任何你想要抓的数据了。

一些常用的代码片段

链接的提取

$crawler->filter($spiderItem->content->link)->each(function($node){
    $url = $node->extract(array('href'));
}

内容的提取

if($crawler1->filter($contentItem->title)->count())
{
	$form['title'] = $crawler1->filter($contentItem->title)->text();
}

分页的处理

if($spiderItem->pagination)
{
    $paginationCount = $crawler->selectLink($spiderItem->pagination)->count();
    if($paginationCount)
    {
        do{
            $linkcount = $crawler->selectLink($spiderItem->pagination)->count();
            if($linkcount == 0) break;
            $pagelink = $crawler->selectLink($spiderItem->pagination)->link();
            $pageurl = $crawler->selectLink($spiderItem->pagination)->extract(array('href'));
            if(empty($pageurl[0])) break;
            $crawler = $goutteClient->click($pagelink);
            try{
                $crawler->filter($spiderItem->content->link)->each(function($node){
                    //处理内容
                 }
            }catch(GuzzleHttp\Exception\ConnectException $e) {
               continue;
            }
           

        }while(!empty($pagelink));            
    }
}

Post Comment