我一直在尝试使用 PHP 和 Goutte 实现刮板。如果我只使用一个线程并按顺序刮掉所有东西,一切都会很好。为了加快这个过程,我希望:
- 加载初始页面,其中包含几个指向需要抓取的页面的链接以及用于分页的链接。
- 为需要抓取的每个链接启动不同的 pthread,以便抓取可以并行进行。
- 一旦从主线程启动了该页面的所有 pthread,主线程将导航到下一页并为该页面中的所有链接重复启动 pthread。
当然,我正在计划一种机制,以确保一次运行的线程数量不超过一定数量。
无论如何,我的问题目前与提供 Goutte 客户端和每个线程的链接有关。
显然,Goutte 客户端是不可序列化的,并且不能在线程构造函数中按原样传递,然后克隆,以便每个线程都有自己的 Goutte 客户端实例。
尝试使用原始客户端的克隆分配线程时出现以下错误:
致命错误:第 15 行 D:\users\Oriol\workspace\TravellScrapper\pagescrapers\baseScraper.php 中的未捕获异常 'Exception' 和消息 'Serialization of 'Closure is not allowed'
这是 Thread 类的代码,它试图在其构造函数中克隆 Goutte 客户端。
class baseScrapper extends Thread{
public function __construct($client, $link){
$this->client = new Client();
$this->client = clone $client;
$this->link = $link;
threadThrottle::addThread();
}
public function run(){
$this->crowler = $this->client->click($this->link);
}
public function __destruct(){
threadThrottle::removeThread();
}
}
关于如何实现这一点的任何建议?我需要在每个线程中复制 Goutte 客户端,以便它包含所有会话信息并且我可以单击链接。