当前位置:AIGC资讯 > 数据采集 > 正文

php QueryList类用规则数组采集列表时出现仅采集一条信息的bug解决

后来仔细阅读了range函数,发现并不是作者的bug,而是我没有理解作者的用意,其实分组采集是在range中规定的,例如采集内容为<ul><li class="item">……</li><li class="item">……</li><li class="item">……</li><li class="item">……</li><li class="item">……</li></ul>,则采集的规则中range应该这样写 $rt->range('.item')……,如此,则采集的内容自动分组,采集结果类似于

Array
(
    [0] => Array
        (
            [title] => 
                        HI83399
                                            
                    化学需氧量【COD】&amp; 酸度pH 多参数测定仪
            [link] => /cn/product/show/602
            [img] => /attached/image/20181227/20181227210839_9930.jpg
        )

    [1] => Array
        (
            [title] => 
                        HI83314
                                            
                    微电脑COD多参数【23参数】光度测定仪
            [link] => /cn/product/show/605
            [img] => /attached/image/20190325/20190325234917_2553.jpg
        )
)

以下是以前的一些误解,不过,也可以借鉴一下。

php的QueryList类真的是一个采集神器,jquery式的选择器让采集变得简单高效,但是最近在采集列表时发现用数组规则采集时有BUG,根据文档中介绍的方法,采集规则数组应该用如下写法。

$rules = [
​    // 采集文章标题
​    'title' => ['h2>a','text'],
​    // 采集链接
​    'link' => ['h2>a','href'],
​    // 采集缩略图
​    'img' => ['.list_thumbnail>img','src'],
​    // 采集文档简介
​    'desc' => ['.memo','text']
];

然而,实际使用发现,这种方法怎么使用都无法采到完全的列表,只能采一条列表,仔细查看文档多次,仍然如此,没有办法只能去读源代码,于是发现源代码中的这段。

switch ($rule['attr']) {
            case 'text':
                $content = $this->allowTags($pqObj->html(), $rule['filter_tags']);
                break;
            case 'texts':
                $content = (new Elements($pqObj))->map(function (Elements $element) use ($rule) {
                    return $this->allowTags($element->html(), $rule['filter_tags']);
                })->all();
                break;
            case 'html':
                $content = $this->stripTags($pqObj->html(), $rule['filter_tags']);
                break;
            case 'htmls':
                $content = (new Elements($pqObj))->map(function (Elements $element) use ($rule) {
                    return $this->stripTags($element->html(), $rule['filter_tags']);
                })->all();
                break;
            case 'htmlOuter':
                $content = $this->stripTags($pqObj->htmlOuter(), $rule['filter_tags']);
                break;
            case 'htmlOuters':
                $content = (new Elements($pqObj))->map(function (Elements $element) use ($rule) {
                    return $this->stripTags($element->htmlOuter(), $rule['filter_tags']);
                })->all();
                break;
            default:
                if(preg_match('/attr\((.+)\)/', $rule['attr'], $arr)) {
                    $content = $pqObj->attr($arr[1]);
                } elseif (preg_match('/attrs\((.+)\)/', $rule['attr'], $arr)) {
                    $content = (new Elements($pqObj))->attrs($arr[1])->all();
                } else {
                    $content = $pqObj->attr($rule['attr']);
                }
                break;
        }

于是,找到采集规则数组的正确写法,如下。

        $rules = [
            'title' => ['.caption1 >a','texts'],
            'url' => ['.caption1 >a','attrs(href)'],
            'time' => ['.time','texts']
        ];

至此,发现不是类的bug,而是文档的错误,即取多条文本用"texts",多条html用'htmls',多条htmlOuter用htmlOuters,采集多条属性用"attrs(属性名)"

更新时间 2023-11-08