C#使用Puppeteer

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.rhkb.cn/news/400022.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring02-springbean生命周期(实例化过程)

【README】 本文总结自《spring揭秘》,作者王福强,非常棒的一本书,墙裂推荐; spring容器根据配置元素组装可用系统分2个阶段,包括spring容器启动, springbean实例化阶段; 本文详细分析springbe…

单播---广播---组播

单播 单播(Unicast)是一种网络通信方式,其中数据包被发送到特定的网络接口。与广播(Broadcast)不同,单播只将数据包发送到目标地址指定的单个接收者。 单播的工作原理: 源地址:发…

DATAX自定义KafkaWriter

因为datax目前不支持写入数据到kafka中,因此本文主要介绍如何基于DataX自定义KafkaWriter,用来同步数据到kafka中。本文偏向实战,datax插件开发理论宝典请参考官方文档: https://github.com/alibaba/DataX/blob/master/dataxPlug…

240810-Gradio通过HTML组件打开本地文件+防止网页跳转到about:blank

A. 最终效果 B. 可通过鼠标点击打开文件,但会跳转到about:blank import gradio as gr import subprocessdef open_pptx():pptx_path /Users/liuguokai/Downloads/240528-工业大模型1.pptxtry:subprocess.Popen([open, pptx_path])return "PPTX file opened s…

【npm】如何将开发的vite插件发布到npm

前言 简单说下 npm 是什么: npm 是一个 node 模块管理工具,也是全球最大的共享源。 npm 工具与 nodejs 配套发布,便利开发人员共享代码。npm 主要包括 npm 官方网站、CLI(控制台命令行工具)、和 registry(…

Python酷库之旅-第三方库Pandas(079)

目录 一、用法精讲 326、pandas.Series.str.normalize方法 326-1、语法 326-2、参数 326-3、功能 326-4、返回值 326-5、说明 326-6、用法 326-6-1、数据准备 326-6-2、代码示例 326-6-3、结果输出 327、pandas.Series.str.pad方法 327-1、语法 327-2、参数 327…

升级软文发稿开源系统源码论文期刊一键发布

升级软文发稿运营管理源码—论文期刊一键发布 软文发稿系统源码(软文发布系统)在基于旧版本的媒介软文发布平台项目改造升级了新的功能模块简称(3.0版)本系统还是基于开源的PHPMYSQLlayui(前端界面)代码进行…

Vue3使用ECharts的曲线条形堆叠混合图

先上效果图 图表容器 <div id"leftChart" style"height: 28vh"></div> <div id"rightChart" style"height: 28vh"></div> 监听resize视图窗口大小&#xff0c;可以让chart图表自适应大小 const leftChart …

wireshark使用介绍及案例分享

一、wireshark介绍 1、定义 wireshark是非常流行的网络封包分析软件,简称小鲨鱼,功能十分强大。可以截取各种网络封包,显示网络封包的详细信息。对应的,linux下的抓包工具是 tcpdump。 1.1、网络基础 参考TCP/IP五层模型,帧结构如下: 帧字段 帧字段含义 Frame 物理层的…

统计学第3天

P值 P值是原假设&#xff08;零假设&#xff09;H0为真的前提下&#xff0c;观察到的异常数据出现的概率。 如果P值很小&#xff0c;意味着原假设为真的情况下&#xff0c;取出能拒绝原假设数据的概率极低&#xff0c;此时取出了一个数据和原假设不符&#xff0c;说明了该组数…

ICMAN水位接近式检测方案(非接触式)

ICMAN水位液位接近式检测方案&#xff08;非接触式&#xff09; 我们的很多家用电器都会需要&#xff1a;液位检测 缺水&溢水提醒保护、高低液位提醒 液位传感器 像健康家电——烧水煮茶熬养生汤的烧水壶、豆浆机、养生壶等需要缺水保护和防溢液提醒&#xff1b; 像清洁…

DAMA学习笔记(十五)-数据管理组织与角色期望

1.引言 随着数据领域的快速发展&#xff0c;组织需要改进管理和治理数据的方式。当前&#xff0c;大多数组织正面临着越来越多的数据。这些数据格式多样、数量 庞大&#xff0c;并来源于不同的渠道。由于数据数量和种类的增加&#xff0c;加剧了数据 管理的复杂性。与此同时&am…

科研绘图系列:R语言多分组箱线图(grouped boxplot)

介绍 分组箱线图(Grouped Boxplot)是一种用于展示不同组别数据分布情况的统计图表。它将箱线图(Boxplot)按照不同的类别或组别进行分组,使得可以同时比较多个组别的数据特征。 箱线图本身是一种标准化的显示数据分布的方法,它能够展示数据的中位数、四分位数以及异常值…

【upload]-ini-[SUCTF 2019]CheckIn-笔记

上传图片木马文件后看到&#xff0c;检查的文件内容&#xff0c;包含<? 一句话木马提示 检查的文件格式 用如下图片木马&#xff0c;加上GIF89a绕过图片和<?检查 GIF89a <script languagephp>eval($_POST[cmd])</script> .user.ini实际上就是一个可以由用…

RAG与LLM原理及实践(11)--- Milvus hybrid search 源码分析及思想

目录 背景 hybrid search 源码分析 WeightedRanker 源码 hybrid search 核心 参数详解 基本入参 扩展入参 aysnc方式代码调用案例 说明 源码逻辑 prepare 调用过程 stub 调用结果 stub 调用过程 blocking 与 async 调用方式 深入内部core weightedRanker 的ch…

UCOSIII事件标志组详解

UCOSIII中的事件标志组是一种用于任务同步和事件管理的机制&#xff0c;它允许任务和中断服务例程&#xff08;ISR&#xff09;发布事件标志&#xff0c;并允许任务等待这些事件标志的发生。以下是对UCOSIII事件标志组的详细介绍&#xff1a; 1. 定义与创建 定义&#xff1a;…

软考:软件设计师 — 13.数据结构

十三. 数据结构 数据结构部分也可参考文章&#xff1a;Java数据结构知识点 — 5种常见数据结构 1. 线性结构 &#xff08;1&#xff09;线性表 顺序表 线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的数据元素&#xff0c;从而使得逻辑上相邻的两个元素…

并行计算模型

像其他专业行话一样&#xff0c;并行计算也有自己的行话。行话就像个大坑&#xff0c;坑中的人需要在其中浸淫很久&#xff0c;才能逐渐适应其语境&#xff0c;然而很多行话的使用常常是草率与不精确的。有时候把鬼都听不懂的行话理解了&#xff0c;再跟别人说鬼话&#xff0c;…

【MySQL 06】表的约束

文章目录 &#x1f308; 一、约束的概念&#x1f308; 二、空属性约束⭐ 1. 空值无法参与运算⭐ 2. 设置非空属性 &#x1f308; 三、默认值约束⭐ 1. 默认值使用案例⭐ 2. 同时设置 not null 和 default &#x1f308; 四、列描述约束&#x1f308; 五、zerofill 补零约束&…

校园外卖平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;菜品信息管理&#xff0c;菜品分类管理&#xff0c;购买菜品管理&#xff0c;订单信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&a…