V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Jaeger
V2EX  ›  PHP

PHP 使用 QueryList 轻松采集 JavaScript 动态渲染页面

  •  1
     
  •   Jaeger · 2017-10-02 12:09:31 +08:00 · 6661 次点击
    这是一个创建于 2617 天前的主题,其中的信息可能已经有所发展或是发生改变。

    QueryList 使用 jQuery 的方式来做采集,拥有丰富的插件。

    下面来演示QueryList使用PhantomJS插件抓取 JS 动态创建的页面内容。

    安装

    使用 Composer 安装:

    • 安装 QueryList
    composer require jaeger/querylist
    

    GitHub: https://github.com/jae-jae/QueryList

    • 安装 PhantomJS 插件
    composer require jaeger/querylist-phantomjs
    
    

    GitHub: https://github.com/jae-jae/QueryList-PhantomJS

    下载 PhantomJS 二进制文件

    PhantomJS 官网:http://phantomjs.org ,下载对应平台的 PhantomJS 二进制文件。

    插件 API

    • QueryList browser($url,$debug = false,$commandOpt = []):使用浏览器打开连接

    使用

    以采集「今日头条」手机版为例,「今日头条」手机版基于 React 框架,内容是纯动态渲染出来的。

    下面演示QueryList的 PhantomJs 插件用法:

    • 安装插件
    use QL\QueryList;
    use QL\Ext\PhantomJs;
    
    $ql = QueryList::getInstance();
    // 安装时需要设置 PhantomJS 二进制文件路径
    $ql->use(PhantomJs::class,'/usr/local/bin/phantomjs');
    //or Custom function name
    $ql->use(PhantomJs::class,'/usr/local/bin/phantomjs','browser');
    
    • Example-1

    获取动态渲染的 HTML:

    $html = $ql->browser('https://m.toutiao.com')->getHtml();
    print_r($html);
    

    获取所有 p 标签文本内容:

    $data = $ql->browser('https://m.toutiao.com')->find('p')->texts();
    print_r($data->all());
    

    输出:

    Array
    (
        [0] => 自拍模式开启!国庆假期我和国旗合个影
        [1] => 你旅途已开始 他们仍在自己的岗位上为你的假期保驾护航
        [2] => 喜极而泣,都教授终于回到地球了!
        //....
    )
    

    使用 http 代理:

    
    // 更多选项可以查看文档: http://phantomjs.org/api/command-line.html
    $ql->browser('https://m.toutiao.com',true,[
    	// 使用 http 代理
    	'--proxy' => '192.168.1.42:8080',
        '--proxy-type' => 'http'
    ])
    
    
    • Example-2

    自定义一个复杂的请求:

    $data = $ql->browser(function (\JonnyW\PhantomJs\Http\RequestInterface $r){
        $r->setMethod('GET');
        $r->setUrl('https://m.toutiao.com');
        $r->setTimeout(10000); // 10 seconds
        $r->setDelay(3); // 3 seconds
        return $r;
    })->find('p')->texts();
    
    print_r($data->all());
    

    开启 debug 模式,并从本地加载 cookie 文件:

    $data = $ql->browser(function (\JonnyW\PhantomJs\Http\RequestInterface $r){
        $r->setMethod('GET');
        $r->setUrl('https://m.toutiao.com');
        $r->setTimeout(10000); // 10 seconds
        $r->setDelay(3); // 3 seconds
        return $r;
    },true,[
        '--cookies-file' => '/path/to/cookies.txt'
    ])->rules([
        'title' => ['p','text'],
        'link' => ['a','href']
    ])->query()->getData();
    
    print_r($data->all());
    
    6 条回复    2017-10-03 07:45:11 +08:00
    hugee
        1
    hugee  
       2017-10-02 12:54:45 +08:00 via Android
    这东西不错
    hahasong
        2
    hahasong  
       2017-10-02 14:48:50 +08:00 via iPhone
    两天实现了 headless
    hronro
        3
    hronro  
       2017-10-02 17:12:35 +08:00 via iPhone
    PhantomJS 已经停止维护了吧,为什么不用 Chrome headless 呢
    HYSS
        4
    HYSS  
       2017-10-02 19:26:56 +08:00
    如何做到不开启 phantomjs 的 用 php 开启 phantomjs ?
    fuxkcsdn
        5
    fuxkcsdn  
       2017-10-02 19:53:25 +08:00 via iPhone
    @hronro 用 Chrome headless 的话还用啥 php😂
    半官方的封装 api https://github.com/GoogleChrome/puppeteer 不要太好用,我是不信会写爬虫的 phper 不会简单的 nodejs
    zackkk
        6
    zackkk  
       2017-10-03 07:45:11 +08:00 via iPhone
    可以理解为,ajax 加载的内容也可以采么
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2670 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 11:17 · PVG 19:17 · LAX 03:17 · JFK 06:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.