C#使用Puppeteer

news/2024/9/10 6:35:45/ 标签: c#, Puppeteer, headless, chromium

Puppeteer

Puppeteer是一个Node.js库,它提供了高级API来通过DevTools协议(Chrome DevTools Protocol https://devtools.chrome.com)控制Chrome或Chromium。 Puppeteer默认情况下无头运行(headless)。

可以配置为运行完整的Chrome或Chromium,运行效果如下

Puppeteer具备以下功能:

1、页面截图和生成PDF

2、抓取动态网页内容

3、自动化表单提交,UI测试,键盘输入等

4、测试Chrome扩展程序

Puppeteer项目地址:

GitHub - puppeteer/puppeteer: JavaScript API for Chrome and Firefox

在C#中调用,是使用了Puppeteer的移植版本,puppeteer-sharp,项目地址:

GitHub - hardkoded/puppeteer-sharp: Headless Chrome .NET API

Puppeteer-sharp是基于.Net Standard 2.0开发,所以可以运行于NET Framework 4.6.1+、 .NET Core 2.0+的版本上.

操作系统的要求是Windows 8+或Windows Server2012+。如果需要在Windows 7上运行Puppeteer-Sharp,则可以通过设置LaunchOptions.WebSocketFactory属性的值为System.Net.WebSockets.Client.Managed来实现。

对于前端开发人员来说,Puppeteer最大的用处应该就是自动化测试,而对于爬虫开发人员,Puppeteer最大的用处是可以很方便的抓取动态网页。Puppeteer就等于是一个人为操作的浏览器,你可以控制它抓取任何动态网页内容。

对比CEF

在前面的文章中,我使用了CEFSharp嵌入到界面中,来进行了动态页面的抓取(https://www.cnblogs.com/zhaotianff/p/9556270.html),

使用Puppeteer也可以达到同样的效果,但它用起来会更加方便, 因为它能以headless方式运行,不用显示在界面上。而且它封装了很多方便开发人员使用的函数。

本质 上来说,Puppeteer是通过Chrome DevTools Protocol来控制Chromium浏览器,而CEF提供了Chromium浏览器本身,它是一个Web Browser控件。

抓取动态页面

1 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
2 var browser = await Puppeteer.LaunchAsync(new LaunchOptions
3             {
4                 Headless = true
5             });
6 var page = await browser.NewPageAsync();
7 await page.GoToAsync("https://www.baidu.com");
8 var html = await page.GetContentAsync();

网页截图

 1   await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);2   browser = await Puppeteer.LaunchAsync(new LaunchOptions3   {4                  Headless = true5   });6   var page = await browser.NewPageAsync();  //打开一个新标签7   await page.GoToAsync("https://www.baidu.com"); //访问页面8  9   
10  //设置截图选项
11  ScreenshotOptions screenshotOptions = new ScreenshotOptions();
12  //screenshotOptions.Clip = new PuppeteerSharp.Media.Clip() { Height = 0, Width = 0, X = 0, Y = 0 };//设置截剪区域
13  screenshotOptions.FullPage = true; //是否截取整个页面
14  screenshotOptions.OmitBackground = false;//是否使用透明背景,而不是默认白色背景
15  screenshotOptions.Quality = 100; //截图质量 0-100(png不可用)
16  screenshotOptions.Type = ScreenshotType.Jpeg; //截图格式
17 
18  await page.ScreenshotAsync("D:\\a.jpg",screenshotOptions);

截图效果如下:

保存网页为PDF

 1 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);2  browser = await Puppeteer.LaunchAsync(new LaunchOptions3  {4                   Headless = true5  });6 var page = await browser.NewPageAsync();  //打开一个新标签7 await page.GoToAsync("https://www.baidu.com"); //访问页面8 9 //设置PDF选项
10 PdfOptions pdfOptions = new PdfOptions();
11 pdfOptions.DisplayHeaderFooter = false; //是否显示页眉页脚
12 pdfOptions.FooterTemplate = "";   //页脚文本
13 pdfOptions.Format = new PuppeteerSharp.Media.PaperFormat(8.27m,11.69m);  //pdf纸张格式 英寸为单位 
14 pdfOptions.HeaderTemplate = "";   //页眉文本
15 pdfOptions.Landscape = false;     //纸张方向 false-垂直 true-水平 
16 pdfOptions.MarginOptions = new PuppeteerSharp.Media.MarginOptions() { Bottom = "0px", Left = "0px", Right = "0px", Top = "0px" }; //纸张边距,需要设置带单位的值,默认值是None
17 pdfOptions.Scale = 1m;            //PDF缩放,从0-1
18 await page.PdfAsync(path, pdfOptions);

保存出来的PDF效果并不怎么好,应该是文档宽高没控制好的原因。

重要说明:

Puppeteer需要先下载Chromium浏览器的相关文件,也就是下面这句代码执行的操作

1 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);

可能会出现下载失败的情况,如下图:

 可以从这里下载 ,并解压到程序运行目录。(推荐这种方式,因为出现了上面的异常,第二种方式中的链接你也访问不了

也可以通过以下方式:

访问google chromium开源镜像网站,下载Chromium浏览器

https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win_x64/

下载后解压到相应位置,然后通过指定Chromium路径来进行初始化

 1 LaunchOptions options = new LaunchOptions();2 options.Headless = true;3 options.DefaultViewport = null;4 //忽略证书错误5 options.IgnoreHTTPSErrors = true;6 7 //chromePath就是下载的Chromium浏览器解压的位置
11 options.ExecutablePath = chromePath;
12 
13 browser = await Puppeteer.LaunchAsync(options);

本文示例代码

GitHub - zhaotianff/PuppeteerDemo: 博客园Puppeteer-Sharp使用示例代码

如果在使用过程中,遇到了问题,可以提个issue给我。

更加详细的Puppeteer使用教程以及爬虫相关知识,可以访问我的github


http://www.ppmy.cn/news/1508599.html

相关文章

oracle rac

1、app连接oracle rac集群 连接到 Oracle RAC(Real Application Clusters)的多种配置方式 1. 使用 JDBC 连接字符串: 使用 JDBC 连接字符串是连接 Oracle RAC 的常见方式。连接字符串的格式如下: jdbc:oracle:thin:(DESCRIPTION…

2024年8月7日(mysql主从 )

回顾 主服务器 [rootmaster_mysql ~]# yum -y install rsync [rootmaster_mysql ~]# tar -xf mysql-8.0.33-linux-glibc2.12-x86_64.tar [rootmaster_mysql ~]# tar -xf mysql-8.0.33-linux-glibc2.12-x86_64.tar.xz [rootmaster_mysql ~]# cp -r mysql-8.0.33-linux-glibc2.…

Docker基础知识大全

文章目录 前言一、Docker为什么出现?二、Docker历史三、Docker能干嘛?四、Docker名词五、Docker安装(CentOS7)六、卸载docker命令七、Docker镜像容器命令总结 1、Docker为什么出现? java jar包 打包项目带上环境&…

RabbitMq如何确保消息不丢失

问题:在生产环境中由于一些不明原因,导致 rabbitmq 重启,在 RabbitMQ 重启期间生产者消息投递失败,导致消息丢失,需要手动处理和恢复。于是,我们开始思考,如何才能进行 RabbitMQ 的消息可靠投递…

Linux驱动入门实验班——基础驱动模板(附百问网视频链接)

目录 一、GPIO子系统 1.确定引脚编号 2.写程序 二、中断函数 使用中断的流程 三、定时器 1.定时器两要素 2.使用定时器 四、交互流程解读 1、非阻塞访问和阻塞访问 2、POLL 3、异步通知 课程链接 一、GPIO子系统 如何驱动GPIO 1.确定引脚编号 可以在开发板上&a…

【网络基础一】几乎不讲任何网络协议细节,搭建网络基本结构

文章目录 问题认识“协议”计算机通信问题技术问题应用问题 协议分层那么网络分层应该怎么分层呢?网络传送宏观流程以太网通信 统编程帮助我们处理数据,网络编程帮助我们获取数据,网络配上我们写的线程池模块很快就搭建起来了。 问题 网卡是…

性能测试工具之JMeter

JMeter Apache JMeter应用程序是开源软件,是一个100%纯Java应用程序,旨在负载测试功能行为和衡量性能。它最初是为测试Web应用程序而设计的,但后来扩展到其他测试功能。 JMeter是一个免费、开源、跨平台的性能测试工具,于20世纪90年代后期面世。这是一个成熟、健全且具有…

智能电话机器人的优势与挑战

1. 工作量比传统人工拨号高单个机器人日呼量可达1000通左右,且同个账号下是可以增加多个电话机器人的,能有效解决话务员基础通话量。 2. 工作状态能一直保持由于是真人语音AI,因此每段对话都是由录音师录制的,经过后期调整了语气…

【数据结构】六、图:3.十字链表、邻接多重表、边集数组

3.十字链表(有向图) 文章目录 3.十字链表(有向图)3.1性能分析 4.邻接多重表(无向图)4.1性能分析 5.边集数组 十字链表是有向图的一种链式存储结构。 不足 对于有向图来说,邻接表是有缺陷的。了…

物理网卡MAC修改器v3.0-直接修改网卡内部硬件MAC地址,重装系统不变!

直接在操作系统里就能修改网卡硬件mac地址,刷新网卡mac序列号硬件码机器码,电脑主板集成网卡,pcie网卡,usb有线网卡,usb无线网卡,英特尔网卡,瑞昱网卡全支持! 一键修改mac&#xff0…

MTK Android12 SystemUI 手势导航 隐藏导航栏底部布局

问题:android12 平台手势导航情况下,app页面未设置全屏情况下,底部导航栏会有一个高度的颜色,底部导航会有一个手势导航提示条 需求:去掉手势导航情况下底部的导航栏和手势提示条 文章目录 相关资源修改问题描述解决方案代码跟踪中间提醒小方块代码查找底部手势导航条跟踪…

洛阳电力设计送变电乙级资质办理的软硬件要求

一、硬件要求 办公场所:必须有固定的办公场所,且面积符合资质标准的要求。 办公场所应具备良好的办公条件,包括但不限于会议室、设计室等。 技术装备:应配备必要的技术装备,包括但不限于计算机、绘图仪、测量仪器等…

HTTP 之 头部信息(二)

HTTP头部是HTTP请求和响应的重要组成部分,它们提供了关于传输的数据的附加信息。HTTP头部由一系列的键值对组成,每个键值对占据一行,键和值由冒号和空格分隔。 通用头部(请求和响应共享) Cache-Control: 控制响应的缓…

React原理之React整体渲染流程

前置知识:深度优先搜索(DFS)、Fiber 节点 在上一篇 React原理篇之 React 整体架构解读中,提到了 Fiber 架构中的几个核心概念: Scheduler(调度器):根据任务的优先级安排任务执行顺序。Reconciler&#xff…

Xcode动态功能加载:深入探索与实践指南

Xcode动态功能加载:深入探索与实践指南 引言 在iOS应用程序开发中,动态功能加载是一项高级技术,它允许开发者在运行时动态加载和卸载应用程序的功能模块。这种技术可以显著提高应用程序的灵活性和可扩展性。本文将详细介绍如何在Xcode中实现…

网站开发涉及到的技术内容介绍——后端PHP(1)

一、PHP简介 PHP(全称:Hypertext Preprocessor (超文本预处理器))是一种创建动态交互性网站的服务器端脚本语言( PHP代码可以放在HTML文档中的任何位置;且PHP 脚本是在服务器上运行,然后将纯 HTML 结果发送回浏览器)且PHP 是免费的,并且使用非常广泛。同类的后端语言有…

【Rust光年纪】深入Rust网络编程:库与框架全方位解析

Rust网络生态:探索异步网络编程利器 前言 随着互联网的迅猛发展和技术的日新月异,越来越多的开发者开始寻找更高效、更稳定的工具和库,以提升他们的项目性能和用户体验。Rust语言作为一种安全、并发、实用的编程语言,其生态系统…

Day16-指针2

数组指针与指针数组 变量指针:指向变量的地址。 数组指针:指向数组的地址。 指针变量:存放其他变量地址的变量。 指针数组:存放数组元素指针的变量。 数组指针 概念:数组指针是指向数组的指针。特点: 先…

AI问答-中台:理解业务中台 Business Middle Office

业务中台(Business Middle Office)是企业在数字化转型过程中构建的一个重要平台,它承载着企业的核心业务能力,并为企业各业务线提供共享的服务和支持。以下是对业务中台的详细理解: 一、定义与性质 定义:…

【Python机器学习】树回归——使用Python的tkinter库创建GUI

机器学习给我们提供了一些强大的工具,能从未知数据中抽取出有用的信息。因此,能否这些信息以易于人们理解的方式呈现十分重要。如果人们可以直接与算法和数据交互,将可以比较轻松的进行解释。其中一个能够同时支持数据呈现和用户交互的方式就…