• php 爬取数据


    对于一般的页面数据我们用querylist可以很容易的抓取页面然后分析其中的dom树,抓取自己需要的数据,存储到数据库,但是有时候会遇到想要抓取的数据通过JavaScript渲染的,这个时候

    Puppeteer 插件就派上用场了,

    composer require nesk/puphpeteer
    npm install @nesk/puphpeteer --->cnpm install @nesk/puphpeteer

    参考https://querylist.cc/docs/guide/v4/Puppeteer,在根据文档来做的时候,发现

     ERROR: Failed to download Chromium r672088! Set "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" env variable to skip download. 错误,

    解决办法 https://npm.taobao.org/package/puppeteer-cn 

    采集网页内容是一项很常见的需求,比较传统的静态页面,curl 就能搞定。但如果页面中有动态加载的内容,比如有些页面里通过 ajax 加载的文章正文内容,又如果有些页面加载完成后进行了一些额外处理(图片地址替换等等……)而你想采集这些处理过后的内容。那么牛逼闪闪的 curl 也束手无策了。

    做过类似需求的人可能会说,老铁,上 PhantomJS 啊!

    没错,这是一个办法,而且在相当长的时间里 PhantomJS 是为数不多的能解决这类需求的工具里的佼佼者。

    但今天这里要介绍的是一个后来居上的工具 -- puppeteer,它是随着 Chrome Headless 技术兴起而快速发展起来的。而且非常关键的是,puppeteer 由 Chrome 的官方团队开发和维护,可以说相当靠谱了!

    puppeteer 是一个 js 包,要想在 Laravel 中使用,得借助于另一神器 spatie/browsershot

     

    安装

    1. 安装 spatie/browsershot

      browsershot 是一个 composer 包,出自于大神团队 spatie

    $ composer require spatie/browsershot
    1. 安装 puppeteer
    $ npm i puppeteer --save

    也可以全局安全 puppeteer 但就个人经验而言,在项目中安装是比较推荐的做法,因为这样不同项目不会同时受全局安装的 puppeteer 影响,此外项目中安装也方便使用 phpdeployer 进行升级(phpdeploy 升级时不会影响线上项目运行,要知道升级 / 安装 puppeteer 可是很费时的,有时候还不能保证一次成功)。

    安装 puppeteer 时会下载 Chromium-Browser,鉴于咱特殊国情,很有可能出现无法下载的情况,对此,就请大家各显神通吧……

     

    使用

    以采集今日头条手机版页面文章内容为例。

    use SpatieBrowsershotBrowsershot;
    
    public function getBodyHtml()
    {
        $newsUrl = 'https://m.toutiao.com/i6546884151050502660/';
    
        $html = Browsershot::url($newsUrl)
            ->windowSize(480, 800)
            ->userAgent('Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36')
            ->mobile()
            ->touch()
            ->bodyHtml();
    
        Log::info($html);
    }

    运行后可以在日志中看到如下内容(截图中只是其中部分)

    img
     

    此外,也可以将页面保存为图片或 PDF 文件。

    use SpatieBrowsershotBrowsershot;
    
    public function getBodyHtml()
    {
        $newsUrl = 'https://m.toutiao.com/i6546884151050502660/';
    
        Browsershot::url($newsUrl)
            ->windowSize(480, 800)
            ->userAgent('Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36')
            ->mobile()
            ->touch()
            ->setDelay(1000)
            ->save(public_path('images/toutiao.jpg'));
    }
    img
     

    图片里那些框与系统字体有关。代码中使用了一个 setDelay () 方法,是为了让内容加载完成后再进行截图,简单粗暴,可能不是最好的解决办法。

     

    可能出现的问题

    • 系统得支持 Chromium 浏览器,当然现在绝大部分浏览器是支持的,要不然也没法,还是用 PhantomJS 吧。

    • 项目中安装了 puppeteer 后调用时有可能出现权限问题,这就需要对项目下 /node_modules/puppeteer 目录赋予适当的权限。

     

    总结

    puppeteer 被应用于测试、采集等场景,是一个非常有力的工具。对于轻度的采集任务,是够用的,比如本文这类在 Laravel (php) 里来用采集一些小页面,但如果需要快速采集大量内容,还是 Python 啥的吧。:smile:

  • 相关阅读:
    css固定底部的四种方法 CSS经典布局-Sticky footer布局
    Vue 中引入jquery
    js在ios中碰到的问题
    解决jq.autocomplete.js插件在三级联动中由于异步请求表单验证卡顿出错问题
    解决vue项目在ie中打开显示空白问题
    vue访问外部链接会拼接默认路径的问题
    jquery.autocomplete联想补全插件及使用中遇到的问题
    360浏览器记住密码状态表单自动填充问题
    JavaScript引入百度地图标注点与坐标偏移问题
    vue项目中开启Eslint碰到的一些问题及其规范
  • 原文地址:https://www.cnblogs.com/sweetsunnyflower/p/11162147.html
Copyright © 2020-2023  润新知