实例:使用puppeteer headless方式抓取JS网页

Puppeteer与无头浏览器:自动化Web页面测试 Puppeteer是一个由Google Chrome团队开发的Node库,它提供了一套高级API来控制Chrome或Chromium浏览器。Puppeteer主要用于无头浏览器的场景,但也可以配置为运行“有头”模式(即常规的浏览器界面)。通过模拟真实用户的操作,如页面导航、表单填写、按钮点击等,Puppeteer在Web自动化测试、爬虫、页面渲染等方面展现出了巨大的潜力。在自动化测试领域,Puppeteer特别受到青睐,原因在于它的灵活性、易用性和功能强大。 阅读详情

puppeteer

google chrome团队出品的puppeteer 是依赖nodejs和chromium的自动化测试库,它的最大优点就是可以处理网页中的动态内容,如JavaScript,能够更好的模拟用户。
有些网站的反爬虫手段是将部分内容隐藏于某些javascript/ajax请求中,致使直接获取a标签的方式不奏效。甚至有些网站会设置隐藏元素“陷阱”,对用户不可见,脚本触发则认为是机器。这种情况下,puppeteer的优势就凸显出来了。
它可实现如下功能:
1. 生成页面的屏幕截图和PDF。
2. 抓取SPA并生成预先呈现的内容(即“SSR”)。
3. 自动表单提交,UI测试,键盘输入等。
4. 创建一个最新的自动化测试环境。使用最新的JavaScript和浏览器功能,直接在最新版本的Chrome中运行测试。
5. 捕获跟踪您网站的时间线,以帮助诊断性能问题。

开源地址:[https://github.com/GoogleChrome/puppeteer/][1]

安装
npm i puppeteer

注意先安装nodejs, 并在nodejs文件根目录下执行(npm文件同级)。
安装过程中会下载chromium,大约120M。

用两天(大约10小时)摸索,绕过了相当多的异步的坑,笔者对puppeteer和nodejs有了一定的掌握。
一张长图,抓取blog文章列表:
这里写图片描述

抓取blog文章

以csdn blog为例,文章内容需要点击“阅读全文”来获取,这就导致只能读取dom的脚本失效。

/**
* load blog.youkuaiyun.com article to local files
**/
const puppeteer = require('puppeteer');
//emulate iphone
const userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1';
const workPath = './contents';
const fs = require("fs");
if (!fs.existsSync(workPath)) {
        fs.mkdirSync(workPath)
}
//base url
const rootUrl = 'https://blog.youkuaiyun.com/';
//max wait milliseconds
const maxWait = 100;
//max loop scroll times
const makLoop = 10;
(async () => {
    let url;
    let countUrl=0;
    const browser = await puppeteer.launch({headless: false});//set headless: true will hide chromium UI
    const page = await browser.newPage();
    await page.setUserAgent(userAgent);
    await page.setViewport({width:414, height:736});
    await page.setRequestInterception(true);
    //filter to block images
    page.on('request', request => {
    if (request.resourceType() === 'image')
      request.abort();
    else
      request.continue();
    });
    await page.goto(rootUrl);

    for(let i= 0; i<makLoop;i++){
        try{
            await page.evaluate(()=>window.scrollTo(0, document.body.scrollHeight));
            await page.waitForNavigation({timeout:maxWait,waitUntil: ['networkidle0']});
        }catch(err){
            console.log('scroll to bottom and then wait '+maxWait+'ms.');
        }
    }
    await page.screenshot({path: workPath+'/screenshot.png',fullPage: true, quality :100, type :'jpeg'});
    //#feedlist_id li[data-type="blog"] a
    const sel = '#feedlist_id li[data-type="blog"] h2 a';
    const hrefs = await page.evaluate((sel) => {
        let elements = Array.from(document.querySelectorAll(sel));
        let links = elements.map(element => {
            return element.href
        })
        return links;
    }, sel);
    console.log('total links: '+hrefs.length);
    process();
  async function process(){
    if(countUrl<hrefs.length){
        url = hrefs[countUrl];
        countUrl++;
    }else{
        browser.close();
        return;
    }
    console.log('processing url: '+url);
    try{
        const tab = await browser.newPage();
        await tab.setUserAgent(userAgent);
        await tab.setViewport({width:414, height:736});
        await tab.setRequestInterception(true);
        //filter to block images
        tab.on('request', request => {
        if (request.resourceType() === 'image')
          request.abort();
        else
          request.continue();
        });
        await tab.goto(url);
        //execute tap request
        try{
            await tab.tap('.read_more_btn');
        }catch(err){
            console.log('there\'s none read more button. No need to TAP');
        }
        let title = await tab.evaluate(() => document.querySelector('#article .article_title').innerText);
        let contents = await tab.evaluate(() => document.querySelector('#article .article_content').innerText);
        contents = 'TITLE: '+title+'\nURL: '+url+'\nCONTENTS: \n'+contents;
        const fs = require("fs");
        fs.writeFileSync(workPath+'/'+tab.url().substring(tab.url().lastIndexOf('/'),tab.url().length)+'.txt',contents);
        console.log(title + " has been downloaded to local.");
        await tab.close();
    }catch(err){
        console.log('url: '+tab.url()+' \n'+err.toString());
    }finally{
        process();
    }

  }
})();

执行过程

录屏可以在我公众号查看,下边是截图:

这里写图片描述

执行结果

文章内容列表:

这里写图片描述

文章内容:

这里写图片描述

结束语

以前就想过既然nodejs是使用JavaScript脚本语言,那么它肯定能处理网页的JavaScript内容,但并没有发现合适的/高效率的库。直到发现puppeteer,才下定决心试水。
话说回来,nodejs的异步真的是很头疼的一件事,这上百行代码我竟然折腾了10个小时。
大家可拓展下代码中process()方法,使用async.eachSeries,我使用的递归方式并不是最优解。
事实上,逐一处理并不高效,原本我写了一个异步的关闭browser方法:

let tryCloseBrowser = setInterval(function(){
        console.log("check if any process running...")
        if(countDown<=0){
          clearInterval(tryCloseBrowser);
          console.log("none process running, close.")
          browser.close();
        }
    },3000);

按照这个思路,代码的最初版本是同时打开多个tab页,效率很高,但容错率很低,大家可以试着自己写一下。

题外话

看过我的文章的人都知道,我写文章更强调处理问题的方式/方法,给大家一些思维上的建议。
对于nodejs和puppeteer我是完全陌生的(当然,我知道他们适合做什么,仅此而已)。如果大家还记得《10倍速程序员》里提到的按需记忆的理念,那么你就会理解我刻意的不去系统的学习新技术。
我说说我接触puppeteer到完成我需要功能的所有思维逻辑:
1. 了解puppeteer功能/特性,结合目的判断是否满足要求。
2. 快速实现getStart中的所有demo
3. 二次判断puppeteer的特性,从设计者角度出发,推测puppeteer的架构。
4. 验证架构。
5. 通读api,了解puppeteer细节。
6. 搜索puppeteer前置学习内容(以及前置学习内容所依赖的前置学习内容)。整理学习内容树,回到1。
7. 设计/分析/调试/……

2018年5月9日02点13分

Node.js与Puppeteer实战:亚马逊商品数据抓取项目详解 Puppeteer的强大之处在于它不仅能“看见”网页,还能“理解”和“互动”。但从工程角度看,真正的难点从来都不是技术本身,而是如何在速度、稳定性与隐蔽性之间找到平衡。未来的趋势很明确:平台的反爬手段只会越来越智能,而我们的应对策略也必须从“硬闯”转向“智取”。无论是利用结构化数据源(如JSON-LD)、还是借助AI识别验证码,亦或是构建分布式代理网络,最终目标都是让自动化行为尽可能贴近真实用户。毕竟,在这场持续升级的攻防战中,谁能更好地模仿人类,谁就能赢得胜利。🤖➡️👤。 阅读详情

相关推荐

机器学习(ML)在材料领域应用

机器学习作为一种兼顾开发效率以及开发成本的方法,已经逐渐应用于材料发现、结构分析、性质预测、反向设计等多个领域,并且在材料学研究中展现出惊人的潜力。传统的发现新材料的方法,如经验试错法和基于密度泛函理论(DFT)的方法,往往需要较长的研发周期,成本高、效率低,已经不能很好的适应如今需求量激增的材料学领域 ...

W5632DE的博客 3718

Puppeteer 使用教程-基础篇(超详细、超全面)

Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。本文涉及了Puppeteer常见常用的API样例,包括爬取图片、视频、cookies设置,字符输入等多方面知识,很全面哦。

~朴:shu的博客 3万+

逆向工程实战:手把手教你破解药监局网站的动态数据加载机制(Python+Chrome开发者工具)

本文详细介绍了如何利用Python和Chrome开发者工具逆向破解药监局网站的动态数据加载机制。通过分析Ajax请求、解析JSON响应数据以及处理动态参数,帮助开发者高效采集动态加载内容,适用于爬虫开发与数据分析场景。

weixin_30832143的博客 68

【Puppeteer】解决在headless为true时的网站反爬虫机制的限制

解决在headless为false时无法访问网站(被爬虫机制限制)的问题

个人学习笔记 3678

手把手教你用srec_cat生成带CRC校验的STM32固件(解决OTA常见校验失败问题)

本文针对STM32 OTA升级中常见的固件校验失败问题,提供了一套使用srec_cat工具自动生成带CRC32校验固件的实战解决方案。文章详细拆解了命令参数,指导开发者如何为固件嵌入CRC值、处理地址偏移及合并文件,从而确保Bootloader能可靠校验固件完整性,提升远程更新的稳定性。

kappa的博客 783

Kile5报错—> ARM-Compiler ‘Default Compiler Version 5‘ which is not available安装使用Compiler Version 5 的办法

Kile5报错—> ARM-Compiler ‘Default Compiler Version 5‘ which is not available安装使用Compiler Version 5 的办法

weixin_72050316的博客 1187

Puppeteer 入门教程

随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666) from:http://www.r9it.com/20171106/puppeteer.html 1、Puppeteer 简介 Puppeteer 是一个node库,他提供了一组用来操纵Chrome的AP...

孤云博客 1万+

QT+QGIS跨平台编译(基于Qt,采用一套代码、一套框架,完成QGIS第三方库、核心库、应用程序的跨平台编译)

QT+QGIS跨平台编译。 基于Qt,采用一套代码、一套框架,完成QGIS第三方库、核心库、应用程序的跨平台编译。

LuckyHanMo的博客 4379

Puppeteer在爬虫领域的应用:如何高效抓取动态网页数据

Puppeteer是一个Node库,它提供了一个高级API来通过DevTools协议控制Chromium或Chrome,特别适合处理动态网页数据抓取。本文将详细介绍Puppeteer在爬虫领域的核心应用,帮助新手快速掌握动态网页数据抓取的技巧。 ## 为什么选择Puppeteer进行动态网页抓取? 传统的静态网页抓取工具(如BeautifulSoup)无法处理JavaScript渲染的内容,而

gitblog_00899的博客 538

【QT开发教程】QMatrix4x4类详解及实战应用:Qt中的4x4矩阵变换

在计算机图形学和三维图形应用中,矩阵变换是一个核心概念。Qt框架提供了QMatrix4x4类,用于处理4x4矩阵变换,帮助开发者在三维空间中进行复杂的几何计算。本文将深入探讨QMatrix4x4的功能及其在Qt应用中的实际应用。

科技改变人类,技术成就未来 725

基于深度学习DNN LSTM网络的光伏发电量预测 完整代码数据 可直接运行

基于深度学习DNN LSTM网络的光伏发电量预测 完整代码数据 可直接运行

2079

Puppeteer与无头浏览器:深入理解Chrome Headless模式的工作原理

Puppeteer是一个强大的JavaScript API,它允许开发者控制Chrome和Firefox浏览器,实现网页自动化、截图、PDF生成等功能。其中,Chrome Headless模式作为Puppeteer的核心特性,为开发者提供了一种无需图形界面即可运行浏览器的高效方式,极大地提升了自动化测试和网页抓取的性能。 ## 🚀 什么是无头浏览器? 无头浏览器(Headless Brows

gitblog_00672的博客 457

【RT-DETR有效改进】计算训练好权重文件对应的FPS、推理每张图片的平均时间(科研必备)

本文给大家带来的改进机制是利用我们训练好的权重文件计算FPS,同时打印每张图片所利用的平均时间,模型大小(以MB为单位),同时支持batch_size功能的选择,对于轻量化模型的读者来说,本文的内容对你一定有帮助,可以清晰帮你展示出模型速度性能的提升以及轻量化的效果(模型大小),对于以提高精度为目的的读者本文也能够帮助大家展示出现阶段的模型速度指标。所以本文的内容是十分有用的机制,对于大家发表论文来说,下面的图片为运行后的效果可以看到,该有的指标均已打印(本文内容为我独家创新,全网无第二份)下面是效果图和文

Snu77的博客 3630

Crawlee JavaScript渲染:处理动态网页内容抓取

在现代网页开发中,许多网站采用JavaScript动态加载内容,这给传统的网页抓取工具带来了挑战。Crawlee作为一款强大的Node.js网页抓取和浏览器自动化库,提供了全面的JavaScript渲染解决方案,帮助开发者轻松应对动态网页内容的抓取需求。 ## 动态网页抓取的挑战 传统的网页抓取工具如CheerioCrawler只能获取服务器返回的原始HTML内容,无法处理由JavaScrip...

gitblog_00386的博客 1110

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Chromium Headless Remote 使用教程

Chromium Headless Remote 使用教程 项目介绍 Chromium Headless Remote 是一个基于 Headless Chromium 的远程调试工具,允许开发者通过远程协议与 Headless Chromium 实例进行交互。该项目的主要目的是简化 Headless Chromium 的使用,使其更容易集成到自动化测试和网页抓取等场景中。 项目快速启动 安装 首先...

gitblog_00902的博客 983

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

rust-headless-chrome完全指南:Rust版Puppeteer快速上手教程

🚀 想要在Rust中实现无头浏览器自动化测试?rust-headless-chrome正是你需要的终极解决方案!作为Rust生态中的Puppeteer等效库,它提供了控制Chrome或Chromium的高级API,让你轻松完成网页截图、PDF生成、JavaScript执行等任务。 ## 什么是rust-headless-chrome? **rust-headless-chrome**是一个基

gitblog_00202的博客 892

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

探索 Puppeteer Heap Snapshot:高效的数据抓取与分析工具

在数字化时代,数据是新的石油。对于开发者而言,如何高效地从网页中提取和分析数据,成为了一项至关重要的技能。今天,我们将介绍一个强大的开源项目——Puppeteer Heap Snapshot,它能够帮助你轻松地捕获和查询网页的堆内存快照,从而实现高效的数据抓取和分析。 ## 项目介绍 Puppeteer Heap Snapshot 是一个基于 Puppeteer 的工具,它允许开发者捕获网页的

gitblog_00437的博客 1047

puppeteer学习(一)——puppeteer与Chrome Headless

puppeteer简介puppeteer是一个node库,是Google chrome团队官方的无界面(headless)chrome工具。它提供了一组用来操纵Chrome的 API,允许通过 JS代码操纵Chrome浏览器,完成数据爬取、Web程序自动测试等任务。Puppeteer项目在[GitHub](https://github.com/GoogleChrome/puppeteer)上开源。

zrxJuly 7397

如何用thal完成你的第一次网页爬虫:Puppeteer页面截图实战教程

想学网页爬虫却不知道从哪里下手?thal 这个基于 Chrome Headless 与 Puppeteer 的实战项目,正是新手入门的最佳教材。它用 Node.js 写好了从 Puppeteer 页面截图、自动登录到抓取数据、存入数据库的完整代码,你只要跟着跑一遍,就能轻松掌握网页爬虫的核心套路,甚至亲手完成自己的第一个爬虫脚本。 ## thal 是什么?一次看懂Puppeteer爬虫项目的完整

gitblog_00127的博客 665

Flutter for OpenHarmony:puppeteer 远程控制 Chrome 浏览器,实现截图与自动化操作(Headless Chrome 适配) 深度解析与鸿蒙适配指南

OpenHarmony远程浏览器控制方案 摘要:本文介绍了如何在OpenHarmony移动设备上通过puppeteer库实现远程浏览器控制功能。由于移动端无法直接运行Chrome,采用Client-Server模式:在PC/云端运行Chrome并开启远程调试端口,OpenHarmony应用通过WebSocket连接进行控制。文章详细讲解了环境配置、核心API使用(包括远程连接、截图和PDF生成)以及OpenHarmony平台适配要点,并提供了一个完整的网页截图查看器示例。该方案适用于爬虫、自动化测试等场景,

2609_95049439的博客 6258

Crawlee 爬虫入门指南:快速搭建专业级网页抓取项目

要把网页上的数据变成自己的 JSON 文件,Node.js 里最顺手的工具是 Crawlee——它把 HTTP 抓取、Cheerio/Playwright/Puppeteer 解析、无头浏览器自动化装进同一个库里,一套 API 走到底。这是一篇重写过的 Crawlee 入门教程,专治「装完不知道下一步」: - 用 CLI 命令一条线完成项目生成与启动; - 3 种爬虫类型的选型标准,附对比表直接

gitblog_00550的博客 738
上一篇: 给老婆的一篇文章
下一篇: 你的知识死角不能否定你的技术能力
蔡永吉
博客等级 码龄17年 102粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值