本文介绍如何用PHP结合QueryList与puphpeteer控制无头Chrome,实现百度搜索结果的动态抓取,涵盖环境配置、核心代码及数据抽取流程。

微信扫一扫

QueryList无头搜索

原创 小蒋 爱名网(22科技集团)
关注
52
20小时前

背景介绍

在数据采集和网络爬虫领域,模拟真实用户行为、获取动态渲染的页面内容一直是关键需求。传统的基于curlfile_get_contents的采集方式,往往无法执行JavaScript,从而难以抓取像百度搜索结果这样依赖前端渲染的数据。

“无头浏览器”(Headless Browser)技术的出现解决了这一问题。它让浏览器在无图形界面的后台运行,但能完整地解析页面、执行脚本。结合PHP的QueryList库和其Puppeteer插件,开发者可以用熟悉的PHP语法,通过控制无头Chrome浏览器来实现复杂的网页交互与数据抓取。

本文介绍的方法,正是利用QueryListpuphpeteer(PHP版的Puppeteer桥接工具)和Chrome,实现了一个可控的、可调试的百度搜索爬虫示例。

核心条件与准备

在开始之前,需要确保环境满足以下条件:

  1. 安装Node.jspuphpeteer依赖于Node.js环境来驱动Puppeteer。

  2. 安装PHP包

    • nesk/puphpeteer:通过npm install @nesk/puphpeteer安装。

    • jaeger/querylistjaeger/querylist-puppeteer:推荐使用Composer安装。

  3. PHP配置:确保proc_open函数未被禁用,因为PHP需要用它来启动子进程(Chrome浏览器)。

  4. 环境建议:原作者提到“不建议用 linux”,这可能是指在某些Linux环境下配置和运行Puppeteer(如依赖库缺失)相对复杂,但在有经验后仍可正常运行。

核心代码与解析

以下代码展示了完整的流程:启动浏览器 -> 访问百度 -> 输入关键词并搜索 -> 等待结果加载 -> 获取页面HTML -> 使用QueryList规则抽取数据 -> 执行额外操作(如保存图片和截图)-> 关闭浏览器。

php
<?php
require ('./vendor/autoload.php');

use QL\QueryList;
use QL\Ext\Chrome;

$ql = QueryList::getInstance();

// 注册Chrome插件,默认方法名为 chrome
$ql->use(Chrome::class);

$html = $ql->chrome(function ($page, $browser) {
    // 1. 访问百度首页
    $page->goto('https://www.baidu.com/');
    sleep(3); // 等待页面加载,方便观察

    // 2. 输入关键词并搜索
    $wd = 'lovesanqing';
    $page->type("input[id='kw']", $wd);
    sleep(1);
    $page->click("input[type='submit']");
    sleep(3); // 等待搜索结果加载

    // 3. 获取渲染完成后的页面HTML
    $html = $page->content();

    // 4. 使用QueryList规则抽取所需数据
    $rules = [
        'title'       => ['#content_left h3 a', 'text'],          // 标题
        'url'         => ['#content_left h3 a', 'href'],          // 链接
        'description' => ['div.c-abstract', 'text'],              // 描述
        'img'         => ['#content_left .general_image_pic a img', 'src'], // 图片
    ];
    $ql = QueryList::html($html);
    $rt = $ql->rules($rules)->query()->getData();
    print_r($rt->all());

    // 5. 数据处理:保存图片到本地
    foreach ($rt->all() as $item) {
        if (isset($item['img'])) {
            $imgUrl = $item['img'];
            $imageContent = file_get_contents($imgUrl);
            $filename = './images/' . time() . rand(1, 999999) . '.jpg';
            file_put_contents($filename, $imageContent);
        }
    }

    // 6. 额外操作:页面截图(裁剪特定区域)
    $screenshotPath = './images/' . time() . rand(1, 999999) . '.jpg';
    $page->screenshot([
        'path' => $screenshotPath,
        'clip' => ['x' => 900, 'y' => 4470, 'width' => 125, 'height' => 40]
    ]);

    sleep(10);
    $browser->close();

    // 闭包必须返回页面的HTML内容
    return $html;
}, [
    'headless' => true,  // 设为false可显示浏览器窗口,方便调试
    'devtools' => false, // 是否打开开发者工具
])->find('title')->text(); // 获取页面标题

// 输出页面标题
echo $html;

代码关键点说明:

  • sleep() 的使用:代码中多次使用sleep(),目的是等待页面元素加载和交互完成。在实际项目中,更推荐使用$page->waitForSelector()等智能等待方法,以提高效率和稳定性。

  • headless 选项:设置为false时会弹出Chrome窗口,非常适合开发调试;生产环境应设为true

  • 数据处理:在获取到数据集合后,代码示例展示了如何遍历并保存图片,以及如何进行页面截图。

总结

本文提供了一种利用PHP结合QueryListPuppeteer(通过puphpeteer)实现无头浏览器采集百度搜索结果的可行方案。

优点:

  • 真实模拟:能完整执行JavaScript,抓取任何动态网页内容。

  • 开发友好:使用PHP语法,并支持可视化调试(headless: false)。

  • 功能丰富:除了数据抽取,还能实现截图、PDF生成、自动化测试等扩展功能。

注意事项与改进建议:

  • 性能开销:启动浏览器进程消耗资源较大,不适合大规模的并发采集。可以考虑复用浏览器实例或使用代理池。

  • 稳定性:依赖外部进程(Node.js和Chrome),需做好异常捕获和超时重试机制。

  • 反爬策略:百度等网站有反爬机制,频繁请求可能触发验证码或IP封禁。建议合理设置请求间隔、使用代理IP,并妥善处理可能出现的验证码(代码中注释了$page->focus()相关操作)。

  • 依赖管理:在Linux服务器上部署时,需确保安装所有Chromium依赖库,这是“不建议用 linux”的潜在原因,但通过正确配置可以解决。

总的来说,对于需要与复杂网页交互的采集任务,这是一个强大且灵活的技术组合。开发者可以根据自身需求和环境,在示例代码基础上进行优化和扩展。

分享 0 曝光 523 浏览 52 互动 0

长按识别分享给好友

长按识别分享给好友

获取域名与品牌保护服务

请告诉我在域名、商标、品牌或知识产权保护等需求或遇到的问题,我们会尽快联系您,为您提供最优质的服务。

提交成功,感谢您的参与

支持 反馈 订阅 数据

长按下方二维码,加我微信

微信号
复制微信号

打开微信加我好友

爱名网

通过微信关注公众号