
浏览器抓取网页
浏览器抓取网页(Jvppeteer本库的灵感来自Puppeteer(Node.js)API)
网站优化 • 优采云 发表了文章 • 0 个评论 • 141 次浏览 • 2021-09-18 05:07
jvppeter
这个库的灵感来源于puppeter(node.JS),API与它基本一致。此库用于方便使用Java操作chrome或chrome
JVMPeter通过devtools控制铬或铬。默认情况下,它在无头模式下运行,或通过配置在“无头”模式下运行
您可以在浏览器中手动执行的大多数操作都可以使用JVMPeter完成!以下是一些例子:
首先,这里是使用依赖关系管理工具(如Maven或gradle)的简要指南。马文
要使用maven,请将此依赖项添加到pom.xml文件:
io.github.fanyong920
jvppeteer
1.1.3
格拉德尔
要使用gradle,请将Maven中央存储库添加到存储库列表中:
mavenCentral()
然后可以将最新版本添加到生成中
compile "io.github.fanyong920:jvppeteer:1.1.3"
伐木
该库使用slf4j进行日志记录,没有任何默认日志记录实现
调试器将日志级别设置为跟踪
独立罐
如果不使用任何依赖项管理工具,可以在此处找到最新的独立JAR
快速启动1、浏览器
//设置基本的启动配置,这里选择了‘有头’模式启动
ArrayList argList = new ArrayList();
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(false).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Puppeteer.launch(options);
在本例中,如果指定启动路径,程序将根据指定路径启动相应的浏览器。如果未指定路径,程序将尝试在默认安装路径下启动Chrome浏览器
2、导航到一个页面
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList argList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(false).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Browser browser2 = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.taobao.com/about/");
browser.close();
Page page1 = browser2.newPage();
page1.goTo("https://www.taobao.com/about/");
在本例中,浏览器导航到特定页面并关闭。此处未指明启动路径。Arglist放置一些额外的命令行启动参数。我将在下面的参考资料部分提供相关信息
3、生成页面的PDF
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList arrayList = new ArrayList();
//生成pdf必须在无厘头模式下才能生效
LaunchOptions options = new LaunchOptionsBuilder().withArgs(arrayList).withHeadless(true).build();
arrayList.add("--no-sandbox");
arrayList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
PDFOptions pdfOptions = new PDFOptions();
pdfOptions.setPath("test.pdf");
page.pdf(pdfOptions);
page.close();
browser.close();
在本例中,导航到某个页面后,拍摄整个页面的屏幕截图,并将其作为PDF文件写入。请注意,生成的PDF必须处于headless模式才能生效
4、TRACING性能分析
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList argList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(true).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
//开启追踪
page.tracing().start("C:\\Users\\howay\\Desktop\\trace.json");
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
page.tracing().stop();
在本例中,页面导航完成后将生成一个JSON文件,其中收录页面性能的特定数据。您可以使用Chrome浏览器开发工具打开JSON文件并分析性能
5、页面截图
BrowserFetcher.downloadIfNotExist(null);
ArrayList arrayList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(arrayList).withHeadless(true).build();
arrayList.add("--no-sandbox");
arrayList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
ScreenshotOptions screenshotOptions = new ScreenshotOptions();
//设置截图范围
Clip clip = new Clip(1.0,1.56,400,400);
screenshotOptions.setClip(clip);
//设置存放的路径
screenshotOptions.setPath("test.png");
page.screenshot(screenshotOptions);
页面导航完成后,设置屏幕截图范围和图像保存路径以启动屏幕截图
更多示例请参见此处
资源devtools protocolchrome命令行启动参数
在此存储库中找到的所有内容都是Apache许可的。有关详细信息,请参阅许可证文件 查看全部
浏览器抓取网页(Jvppeteer本库的灵感来自Puppeteer(Node.js)API)
jvppeter
这个库的灵感来源于puppeter(node.JS),API与它基本一致。此库用于方便使用Java操作chrome或chrome
JVMPeter通过devtools控制铬或铬。默认情况下,它在无头模式下运行,或通过配置在“无头”模式下运行
您可以在浏览器中手动执行的大多数操作都可以使用JVMPeter完成!以下是一些例子:
首先,这里是使用依赖关系管理工具(如Maven或gradle)的简要指南。马文
要使用maven,请将此依赖项添加到pom.xml文件:
io.github.fanyong920
jvppeteer
1.1.3
格拉德尔
要使用gradle,请将Maven中央存储库添加到存储库列表中:
mavenCentral()
然后可以将最新版本添加到生成中
compile "io.github.fanyong920:jvppeteer:1.1.3"
伐木
该库使用slf4j进行日志记录,没有任何默认日志记录实现
调试器将日志级别设置为跟踪
独立罐
如果不使用任何依赖项管理工具,可以在此处找到最新的独立JAR
快速启动1、浏览器
//设置基本的启动配置,这里选择了‘有头’模式启动
ArrayList argList = new ArrayList();
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(false).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Puppeteer.launch(options);
在本例中,如果指定启动路径,程序将根据指定路径启动相应的浏览器。如果未指定路径,程序将尝试在默认安装路径下启动Chrome浏览器
2、导航到一个页面
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList argList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(false).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Browser browser2 = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.taobao.com/about/");
browser.close();
Page page1 = browser2.newPage();
page1.goTo("https://www.taobao.com/about/");
在本例中,浏览器导航到特定页面并关闭。此处未指明启动路径。Arglist放置一些额外的命令行启动参数。我将在下面的参考资料部分提供相关信息
3、生成页面的PDF
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList arrayList = new ArrayList();
//生成pdf必须在无厘头模式下才能生效
LaunchOptions options = new LaunchOptionsBuilder().withArgs(arrayList).withHeadless(true).build();
arrayList.add("--no-sandbox");
arrayList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
PDFOptions pdfOptions = new PDFOptions();
pdfOptions.setPath("test.pdf");
page.pdf(pdfOptions);
page.close();
browser.close();
在本例中,导航到某个页面后,拍摄整个页面的屏幕截图,并将其作为PDF文件写入。请注意,生成的PDF必须处于headless模式才能生效
4、TRACING性能分析
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList argList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(true).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
//开启追踪
page.tracing().start("C:\\Users\\howay\\Desktop\\trace.json");
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
page.tracing().stop();
在本例中,页面导航完成后将生成一个JSON文件,其中收录页面性能的特定数据。您可以使用Chrome浏览器开发工具打开JSON文件并分析性能
5、页面截图
BrowserFetcher.downloadIfNotExist(null);
ArrayList arrayList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(arrayList).withHeadless(true).build();
arrayList.add("--no-sandbox");
arrayList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
ScreenshotOptions screenshotOptions = new ScreenshotOptions();
//设置截图范围
Clip clip = new Clip(1.0,1.56,400,400);
screenshotOptions.setClip(clip);
//设置存放的路径
screenshotOptions.setPath("test.png");
page.screenshot(screenshotOptions);
页面导航完成后,设置屏幕截图范围和图像保存路径以启动屏幕截图
更多示例请参见此处
资源devtools protocolchrome命令行启动参数
在此存储库中找到的所有内容都是Apache许可的。有关详细信息,请参阅许可证文件
浏览器抓取网页(我试图通过代码来获取一个网页的HTML版本:)
网站优化 • 优采云 发表了文章 • 0 个评论 • 91 次浏览 • 2021-09-18 05:00
我试图通过代码获取网页的HTML版本:GET403异常抓取网页编程,即使网页是通过浏览器
WebRequest r = WebRequest.Create(szPageURL);
WebClient client = new WebClient();
try
{
WebResponse resp = r.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
szHTML = sr.ReadToEnd();
}
当我使用像URL这样的东西时,这段代码是有效的。Com,或。但是,当我输入(在URL参数中使用“HTTP”或“HTTPS”)时,在执行R.getresponse()时会出现403异常。但是我可以很容易地在浏览器中手动获取页面。我得到的异常是403(禁止),异常状态成员说“protocolerror”。你这是什么意思?为什么我要在实际可用的页面上获取这些信息?有人有主意吗?多谢各位
顺便说一下,我也试过:
string downloadString = client.DownloadString(szPageURL);
得到完全相同的异常
来源
2017-02-08lerxst3 查看全部
浏览器抓取网页(我试图通过代码来获取一个网页的HTML版本:)
我试图通过代码获取网页的HTML版本:GET403异常抓取网页编程,即使网页是通过浏览器
WebRequest r = WebRequest.Create(szPageURL);
WebClient client = new WebClient();
try
{
WebResponse resp = r.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
szHTML = sr.ReadToEnd();
}
当我使用像URL这样的东西时,这段代码是有效的。Com,或。但是,当我输入(在URL参数中使用“HTTP”或“HTTPS”)时,在执行R.getresponse()时会出现403异常。但是我可以很容易地在浏览器中手动获取页面。我得到的异常是403(禁止),异常状态成员说“protocolerror”。你这是什么意思?为什么我要在实际可用的页面上获取这些信息?有人有主意吗?多谢各位
顺便说一下,我也试过:
string downloadString = client.DownloadString(szPageURL);
得到完全相同的异常
来源
2017-02-08lerxst3
浏览器抓取网页(TianFang-使用ScrapySharp快速从网页中采集数据这里的CSS选择器)
网站优化 • 优采云 发表了文章 • 0 个评论 • 191 次浏览 • 2021-09-18 04:24
我们需要使用市、区、县居委会对应的区号,所以我们可以在统计局的网页上找到这些数据。我们使用htmlagilitypack和scrapsharp。因为这也是第一次从网页捕获数据,所以我们不熟悉htmlagilitypack和scrapsharp的使用。在此期间,我们遇到了许多问题。这里是一个总结
对于htmlagilitypack和scrapysharp的使用,互联网上有很多演示。然而,看起来他们基本上是同一篇文章,我不知道谁是原作者。如果你把天方的博客放在这里,你就不会复制演示,而是附上一个链接,如果你需要的话,你可以看一看
天方-使用scrapysharp从网页中快速提取采集数据
这里CSS选择器的使用非常简单,就像我们编写CSS来定位HTML元素一样。统计局网站的内容如下图所示
一行中有四组表,我们获取的数据不仅仅是一个页面的内容,因此我们只能在这里找到统一的规律。最后,我们直接使用简单而粗略的方法var divs=HTML。Cssselect(“table tr”)//直接获取最低表的tr
在获得相应的值后,会遇到另一个问题。无论捕获的数据是读取到控制应用程序控制台还是保存在文本中,中文读取都是一个问号。最后,我们发现这是格式编码的问题。演示中网页的格式编码是UTF-8,scrapysharp捕获的默认格式编码也应该是UTF-8,所以不会有问题,统计局的编码格式是gbk2312。由于请求的捕获数据没有使用正确的编码格式,因此捕获的数据会变得混乱
如前所述,百度搜索基本上是天方的博客文章。类似的问题根本没有解决方案,也找不到scrapysharp的使用文档。最后,在一个边际的文章. 代码如下
到目前为止,web内容的捕获基本上是成功的,因此启动该程序并让它捕获数据
但是,在运行程序的过程中遇到的一个问题是,有时网络不稳定或访问网站太频繁,导致502错误,程序将报告异常。我的解决方案是使用try-catch抓取网页内容。如果不正常,则为内容分配一个空字符串,并让其继续运行,因此没有问题,但是,这不是一个好的解决方案。然而,目前的容量是有限的,所以我们只能先使用它 查看全部
浏览器抓取网页(TianFang-使用ScrapySharp快速从网页中采集数据这里的CSS选择器)
我们需要使用市、区、县居委会对应的区号,所以我们可以在统计局的网页上找到这些数据。我们使用htmlagilitypack和scrapsharp。因为这也是第一次从网页捕获数据,所以我们不熟悉htmlagilitypack和scrapsharp的使用。在此期间,我们遇到了许多问题。这里是一个总结
对于htmlagilitypack和scrapysharp的使用,互联网上有很多演示。然而,看起来他们基本上是同一篇文章,我不知道谁是原作者。如果你把天方的博客放在这里,你就不会复制演示,而是附上一个链接,如果你需要的话,你可以看一看
天方-使用scrapysharp从网页中快速提取采集数据
这里CSS选择器的使用非常简单,就像我们编写CSS来定位HTML元素一样。统计局网站的内容如下图所示
一行中有四组表,我们获取的数据不仅仅是一个页面的内容,因此我们只能在这里找到统一的规律。最后,我们直接使用简单而粗略的方法var divs=HTML。Cssselect(“table tr”)//直接获取最低表的tr
在获得相应的值后,会遇到另一个问题。无论捕获的数据是读取到控制应用程序控制台还是保存在文本中,中文读取都是一个问号。最后,我们发现这是格式编码的问题。演示中网页的格式编码是UTF-8,scrapysharp捕获的默认格式编码也应该是UTF-8,所以不会有问题,统计局的编码格式是gbk2312。由于请求的捕获数据没有使用正确的编码格式,因此捕获的数据会变得混乱
如前所述,百度搜索基本上是天方的博客文章。类似的问题根本没有解决方案,也找不到scrapysharp的使用文档。最后,在一个边际的文章. 代码如下
到目前为止,web内容的捕获基本上是成功的,因此启动该程序并让它捕获数据
但是,在运行程序的过程中遇到的一个问题是,有时网络不稳定或访问网站太频繁,导致502错误,程序将报告异常。我的解决方案是使用try-catch抓取网页内容。如果不正常,则为内容分配一个空字符串,并让其继续运行,因此没有问题,但是,这不是一个好的解决方案。然而,目前的容量是有限的,所以我们只能先使用它
浏览器抓取网页(puppeteergoogle团队出品的puppeteer和浏览器功能)
网站优化 • 优采云 发表了文章 • 0 个评论 • 228 次浏览 • 2021-09-18 04:21
木偶演员
GoogleChrome团队生产的puppeter是一个依靠nodejs和Chrome的自动化测试库。它最大的优点是可以处理网页中的动态内容,如JavaScript,并更好地模拟用户
一些网站反爬虫方法在一些JavaScript/Ajax请求中隐藏了部分内容,这使得直接获取a标记的方法无效。有些网站甚至会设置用户看不见的隐藏元素“陷阱”,脚本触发器被认为是机器。在这种情况下,木偶师的优势就突出了
可实现以下功能:
1.生成页面的截图和PDF
2.抓取spa并生成预渲染内容(即“SSR”)
3.自动表单提交、UI测试、键盘输入等
4.创建最新的自动化测试环境。使用最新的JavaScript和浏览器功能直接在最新版本的chrome中运行测试
5.捕获并跟踪您的网站时间线,以帮助诊断性能问题
开放源代码地址:[]1]
装置
npm i puppeteer
注意:首先安装nodejs并在nodejs文件的根目录下执行(同一级别的NPM文件)
铬将在安装过程中下载,约120m
花了两天(约10小时)的时间探索并绕过了大量的异步坑。作者对木偶演员和舞者有一定的掌握
长照片、抓拍blog文章List:
抓住blog文章
以CSDN博客为例,文章内容需要通过点击“读取全文”获取,这导致只能读取dom的脚本失效
/**
* load blog.csdn.net 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.csdn.net/';
//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; iwindow.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 {
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();
}
}
})();
执行过程
录音机可以在我的官方帐户中查看,屏幕截图如下:
执行结果
文章内容列表:
文章content:
结论
我认为由于nodejs使用JavaScript脚本语言,它当然可以处理web页面的JavaScript内容,但我没有找到合适/高效的库。直到找到木偶师,我才下定决心试水
换句话说,nodejs的异步性确实令人头痛。我已经花了10个小时写了几百行代码
您可以在代码中展开process()方法并使用async.eachseries。我使用的递归方法不是最佳解决方案
事实上,逐个处理是没有效率的。我最初编写了一个异步方法来关闭浏览器:
<p>let tryCloseBrowser = setInterval(function(){
console.log("check if any process running...")
if(countDown 查看全部
浏览器抓取网页(puppeteergoogle团队出品的puppeteer和浏览器功能)
木偶演员
GoogleChrome团队生产的puppeter是一个依靠nodejs和Chrome的自动化测试库。它最大的优点是可以处理网页中的动态内容,如JavaScript,并更好地模拟用户
一些网站反爬虫方法在一些JavaScript/Ajax请求中隐藏了部分内容,这使得直接获取a标记的方法无效。有些网站甚至会设置用户看不见的隐藏元素“陷阱”,脚本触发器被认为是机器。在这种情况下,木偶师的优势就突出了
可实现以下功能:
1.生成页面的截图和PDF
2.抓取spa并生成预渲染内容(即“SSR”)
3.自动表单提交、UI测试、键盘输入等
4.创建最新的自动化测试环境。使用最新的JavaScript和浏览器功能直接在最新版本的chrome中运行测试
5.捕获并跟踪您的网站时间线,以帮助诊断性能问题
开放源代码地址:[]1]
装置
npm i puppeteer
注意:首先安装nodejs并在nodejs文件的根目录下执行(同一级别的NPM文件)
铬将在安装过程中下载,约120m
花了两天(约10小时)的时间探索并绕过了大量的异步坑。作者对木偶演员和舞者有一定的掌握
长照片、抓拍blog文章List:
抓住blog文章
以CSDN博客为例,文章内容需要通过点击“读取全文”获取,这导致只能读取dom的脚本失效
/**
* load blog.csdn.net 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.csdn.net/';
//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; iwindow.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 {
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();
}
}
})();
执行过程
录音机可以在我的官方帐户中查看,屏幕截图如下:
执行结果
文章内容列表:
文章content:
结论
我认为由于nodejs使用JavaScript脚本语言,它当然可以处理web页面的JavaScript内容,但我没有找到合适/高效的库。直到找到木偶师,我才下定决心试水
换句话说,nodejs的异步性确实令人头痛。我已经花了10个小时写了几百行代码
您可以在代码中展开process()方法并使用async.eachseries。我使用的递归方法不是最佳解决方案
事实上,逐个处理是没有效率的。我最初编写了一个异步方法来关闭浏览器:
<p>let tryCloseBrowser = setInterval(function(){
console.log("check if any process running...")
if(countDown
浏览器抓取网页(浏览器上如何渲染出图形数据的文本渲染方式?)
网站优化 • 优采云 发表了文章 • 0 个评论 • 121 次浏览 • 2021-09-17 10:03
浏览器抓取网页数据,我们知道网页上获取数据的方式有http协议的文本,https协议的http请求,post请求等,这三种方式那种更加稳定呢?针对这个问题,我们可以通过页面的webgl加速,webgl实际上是一种通用计算机图形接口(gpu)或webgl浏览器应用接口(svg),目前webgl已成为web及桌面界面开发的标准工具。
其与webgl实现的原理分为三种:原生代码:和java(ie7及更高)一样,以c++、objective-c、swift或java交叉编译,获取数据原生客户端:原生代码,以opengles2.0实现,即使有浏览器提供api接口,渲染服务器也不提供。图形协议:不需要渲染服务器渲染,以image/svg/flash等格式直接输出html内容,用户也可以直接浏览html代码。
接下来我们就尝试探讨一下三种渲染方式在访问时,在浏览器上如何渲染出图形数据,从而达到最终效果。文本渲染通过浏览器来抓取网页的内容时,直接抓取网页数据。网页将传输给flash,从而flash获取该数据并显示出来。对于该行为,涉及两部分的技术,首先是图形应用程序,第二是浏览器。下面我们就分别来看一下,webgl在这两部分技术上都做了哪些工作,他们分别是如何将图形输出到浏览器中的。
1.图形应用程序:可能是graphicsbuilder,或者是c++语言的webgl库。这个是完全出于项目开发考虑,首先项目考虑将脚本逻辑放在对应的模块中,同时通过graphicsbuilder这个脚本库,集成图形绘制能力,graphicsbuilder是一个webgl库,下面我们就介绍其中的一个部分,graphicsbuilder2.1如何传入该图形程序打开浏览器,打开图形控制台输入:webgl-toolbox,然后回车,就会执行webgl图形控制台脚本,然后编译生成graphicsbuilder2.2如何传递数据假设我们通过http协议发送了一个html格式的网页数据,里面包含一个链接,点击这个链接,再点击发送数据。
在urlencode-to-binary中传递:{"this-url":"","actions":[{"type":"minimal","type":"success","data":{"attitude":["90","85","95"],"tightness":"30","left":["22","23","25"],"height":["145","144","166"],"width":["320","640","362"],"min":1135,"max":"3332","offset":["1","2","3"],"onleft":["322","822","912"],"onright":["322","842","833"],"connection。 查看全部
浏览器抓取网页(浏览器上如何渲染出图形数据的文本渲染方式?)
浏览器抓取网页数据,我们知道网页上获取数据的方式有http协议的文本,https协议的http请求,post请求等,这三种方式那种更加稳定呢?针对这个问题,我们可以通过页面的webgl加速,webgl实际上是一种通用计算机图形接口(gpu)或webgl浏览器应用接口(svg),目前webgl已成为web及桌面界面开发的标准工具。
其与webgl实现的原理分为三种:原生代码:和java(ie7及更高)一样,以c++、objective-c、swift或java交叉编译,获取数据原生客户端:原生代码,以opengles2.0实现,即使有浏览器提供api接口,渲染服务器也不提供。图形协议:不需要渲染服务器渲染,以image/svg/flash等格式直接输出html内容,用户也可以直接浏览html代码。
接下来我们就尝试探讨一下三种渲染方式在访问时,在浏览器上如何渲染出图形数据,从而达到最终效果。文本渲染通过浏览器来抓取网页的内容时,直接抓取网页数据。网页将传输给flash,从而flash获取该数据并显示出来。对于该行为,涉及两部分的技术,首先是图形应用程序,第二是浏览器。下面我们就分别来看一下,webgl在这两部分技术上都做了哪些工作,他们分别是如何将图形输出到浏览器中的。
1.图形应用程序:可能是graphicsbuilder,或者是c++语言的webgl库。这个是完全出于项目开发考虑,首先项目考虑将脚本逻辑放在对应的模块中,同时通过graphicsbuilder这个脚本库,集成图形绘制能力,graphicsbuilder是一个webgl库,下面我们就介绍其中的一个部分,graphicsbuilder2.1如何传入该图形程序打开浏览器,打开图形控制台输入:webgl-toolbox,然后回车,就会执行webgl图形控制台脚本,然后编译生成graphicsbuilder2.2如何传递数据假设我们通过http协议发送了一个html格式的网页数据,里面包含一个链接,点击这个链接,再点击发送数据。
在urlencode-to-binary中传递:{"this-url":"","actions":[{"type":"minimal","type":"success","data":{"attitude":["90","85","95"],"tightness":"30","left":["22","23","25"],"height":["145","144","166"],"width":["320","640","362"],"min":1135,"max":"3332","offset":["1","2","3"],"onleft":["322","822","912"],"onright":["322","842","833"],"connection。
浏览器抓取网页(Jvppeteer本库的灵感来自Puppeteer(Node.js)API)
网站优化 • 优采云 发表了文章 • 0 个评论 • 141 次浏览 • 2021-09-18 05:07
jvppeter
这个库的灵感来源于puppeter(node.JS),API与它基本一致。此库用于方便使用Java操作chrome或chrome
JVMPeter通过devtools控制铬或铬。默认情况下,它在无头模式下运行,或通过配置在“无头”模式下运行
您可以在浏览器中手动执行的大多数操作都可以使用JVMPeter完成!以下是一些例子:
首先,这里是使用依赖关系管理工具(如Maven或gradle)的简要指南。马文
要使用maven,请将此依赖项添加到pom.xml文件:
io.github.fanyong920
jvppeteer
1.1.3
格拉德尔
要使用gradle,请将Maven中央存储库添加到存储库列表中:
mavenCentral()
然后可以将最新版本添加到生成中
compile "io.github.fanyong920:jvppeteer:1.1.3"
伐木
该库使用slf4j进行日志记录,没有任何默认日志记录实现
调试器将日志级别设置为跟踪
独立罐
如果不使用任何依赖项管理工具,可以在此处找到最新的独立JAR
快速启动1、浏览器
//设置基本的启动配置,这里选择了‘有头’模式启动
ArrayList argList = new ArrayList();
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(false).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Puppeteer.launch(options);
在本例中,如果指定启动路径,程序将根据指定路径启动相应的浏览器。如果未指定路径,程序将尝试在默认安装路径下启动Chrome浏览器
2、导航到一个页面
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList argList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(false).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Browser browser2 = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.taobao.com/about/");
browser.close();
Page page1 = browser2.newPage();
page1.goTo("https://www.taobao.com/about/");
在本例中,浏览器导航到特定页面并关闭。此处未指明启动路径。Arglist放置一些额外的命令行启动参数。我将在下面的参考资料部分提供相关信息
3、生成页面的PDF
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList arrayList = new ArrayList();
//生成pdf必须在无厘头模式下才能生效
LaunchOptions options = new LaunchOptionsBuilder().withArgs(arrayList).withHeadless(true).build();
arrayList.add("--no-sandbox");
arrayList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
PDFOptions pdfOptions = new PDFOptions();
pdfOptions.setPath("test.pdf");
page.pdf(pdfOptions);
page.close();
browser.close();
在本例中,导航到某个页面后,拍摄整个页面的屏幕截图,并将其作为PDF文件写入。请注意,生成的PDF必须处于headless模式才能生效
4、TRACING性能分析
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList argList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(true).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
//开启追踪
page.tracing().start("C:\\Users\\howay\\Desktop\\trace.json");
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
page.tracing().stop();
在本例中,页面导航完成后将生成一个JSON文件,其中收录页面性能的特定数据。您可以使用Chrome浏览器开发工具打开JSON文件并分析性能
5、页面截图
BrowserFetcher.downloadIfNotExist(null);
ArrayList arrayList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(arrayList).withHeadless(true).build();
arrayList.add("--no-sandbox");
arrayList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
ScreenshotOptions screenshotOptions = new ScreenshotOptions();
//设置截图范围
Clip clip = new Clip(1.0,1.56,400,400);
screenshotOptions.setClip(clip);
//设置存放的路径
screenshotOptions.setPath("test.png");
page.screenshot(screenshotOptions);
页面导航完成后,设置屏幕截图范围和图像保存路径以启动屏幕截图
更多示例请参见此处
资源devtools protocolchrome命令行启动参数
在此存储库中找到的所有内容都是Apache许可的。有关详细信息,请参阅许可证文件 查看全部
浏览器抓取网页(Jvppeteer本库的灵感来自Puppeteer(Node.js)API)
jvppeter
这个库的灵感来源于puppeter(node.JS),API与它基本一致。此库用于方便使用Java操作chrome或chrome
JVMPeter通过devtools控制铬或铬。默认情况下,它在无头模式下运行,或通过配置在“无头”模式下运行
您可以在浏览器中手动执行的大多数操作都可以使用JVMPeter完成!以下是一些例子:
首先,这里是使用依赖关系管理工具(如Maven或gradle)的简要指南。马文
要使用maven,请将此依赖项添加到pom.xml文件:
io.github.fanyong920
jvppeteer
1.1.3
格拉德尔
要使用gradle,请将Maven中央存储库添加到存储库列表中:
mavenCentral()
然后可以将最新版本添加到生成中
compile "io.github.fanyong920:jvppeteer:1.1.3"
伐木
该库使用slf4j进行日志记录,没有任何默认日志记录实现
调试器将日志级别设置为跟踪
独立罐
如果不使用任何依赖项管理工具,可以在此处找到最新的独立JAR
快速启动1、浏览器
//设置基本的启动配置,这里选择了‘有头’模式启动
ArrayList argList = new ArrayList();
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(false).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Puppeteer.launch(options);
在本例中,如果指定启动路径,程序将根据指定路径启动相应的浏览器。如果未指定路径,程序将尝试在默认安装路径下启动Chrome浏览器
2、导航到一个页面
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList argList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(false).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Browser browser2 = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.taobao.com/about/");
browser.close();
Page page1 = browser2.newPage();
page1.goTo("https://www.taobao.com/about/");
在本例中,浏览器导航到特定页面并关闭。此处未指明启动路径。Arglist放置一些额外的命令行启动参数。我将在下面的参考资料部分提供相关信息
3、生成页面的PDF
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList arrayList = new ArrayList();
//生成pdf必须在无厘头模式下才能生效
LaunchOptions options = new LaunchOptionsBuilder().withArgs(arrayList).withHeadless(true).build();
arrayList.add("--no-sandbox");
arrayList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
PDFOptions pdfOptions = new PDFOptions();
pdfOptions.setPath("test.pdf");
page.pdf(pdfOptions);
page.close();
browser.close();
在本例中,导航到某个页面后,拍摄整个页面的屏幕截图,并将其作为PDF文件写入。请注意,生成的PDF必须处于headless模式才能生效
4、TRACING性能分析
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList argList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(argList).withHeadless(true).build();
argList.add("--no-sandbox");
argList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
//开启追踪
page.tracing().start("C:\\Users\\howay\\Desktop\\trace.json");
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
page.tracing().stop();
在本例中,页面导航完成后将生成一个JSON文件,其中收录页面性能的特定数据。您可以使用Chrome浏览器开发工具打开JSON文件并分析性能
5、页面截图
BrowserFetcher.downloadIfNotExist(null);
ArrayList arrayList = new ArrayList();
LaunchOptions options = new LaunchOptionsBuilder().withArgs(arrayList).withHeadless(true).build();
arrayList.add("--no-sandbox");
arrayList.add("--disable-setuid-sandbox");
Browser browser = Puppeteer.launch(options);
Page page = browser.newPage();
page.goTo("https://www.baidu.com/%3Ftn%3D ... 6quot;);
ScreenshotOptions screenshotOptions = new ScreenshotOptions();
//设置截图范围
Clip clip = new Clip(1.0,1.56,400,400);
screenshotOptions.setClip(clip);
//设置存放的路径
screenshotOptions.setPath("test.png");
page.screenshot(screenshotOptions);
页面导航完成后,设置屏幕截图范围和图像保存路径以启动屏幕截图
更多示例请参见此处
资源devtools protocolchrome命令行启动参数
在此存储库中找到的所有内容都是Apache许可的。有关详细信息,请参阅许可证文件
浏览器抓取网页(我试图通过代码来获取一个网页的HTML版本:)
网站优化 • 优采云 发表了文章 • 0 个评论 • 91 次浏览 • 2021-09-18 05:00
我试图通过代码获取网页的HTML版本:GET403异常抓取网页编程,即使网页是通过浏览器
WebRequest r = WebRequest.Create(szPageURL);
WebClient client = new WebClient();
try
{
WebResponse resp = r.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
szHTML = sr.ReadToEnd();
}
当我使用像URL这样的东西时,这段代码是有效的。Com,或。但是,当我输入(在URL参数中使用“HTTP”或“HTTPS”)时,在执行R.getresponse()时会出现403异常。但是我可以很容易地在浏览器中手动获取页面。我得到的异常是403(禁止),异常状态成员说“protocolerror”。你这是什么意思?为什么我要在实际可用的页面上获取这些信息?有人有主意吗?多谢各位
顺便说一下,我也试过:
string downloadString = client.DownloadString(szPageURL);
得到完全相同的异常
来源
2017-02-08lerxst3 查看全部
浏览器抓取网页(我试图通过代码来获取一个网页的HTML版本:)
我试图通过代码获取网页的HTML版本:GET403异常抓取网页编程,即使网页是通过浏览器
WebRequest r = WebRequest.Create(szPageURL);
WebClient client = new WebClient();
try
{
WebResponse resp = r.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
szHTML = sr.ReadToEnd();
}
当我使用像URL这样的东西时,这段代码是有效的。Com,或。但是,当我输入(在URL参数中使用“HTTP”或“HTTPS”)时,在执行R.getresponse()时会出现403异常。但是我可以很容易地在浏览器中手动获取页面。我得到的异常是403(禁止),异常状态成员说“protocolerror”。你这是什么意思?为什么我要在实际可用的页面上获取这些信息?有人有主意吗?多谢各位
顺便说一下,我也试过:
string downloadString = client.DownloadString(szPageURL);
得到完全相同的异常
来源
2017-02-08lerxst3
浏览器抓取网页(TianFang-使用ScrapySharp快速从网页中采集数据这里的CSS选择器)
网站优化 • 优采云 发表了文章 • 0 个评论 • 191 次浏览 • 2021-09-18 04:24
我们需要使用市、区、县居委会对应的区号,所以我们可以在统计局的网页上找到这些数据。我们使用htmlagilitypack和scrapsharp。因为这也是第一次从网页捕获数据,所以我们不熟悉htmlagilitypack和scrapsharp的使用。在此期间,我们遇到了许多问题。这里是一个总结
对于htmlagilitypack和scrapysharp的使用,互联网上有很多演示。然而,看起来他们基本上是同一篇文章,我不知道谁是原作者。如果你把天方的博客放在这里,你就不会复制演示,而是附上一个链接,如果你需要的话,你可以看一看
天方-使用scrapysharp从网页中快速提取采集数据
这里CSS选择器的使用非常简单,就像我们编写CSS来定位HTML元素一样。统计局网站的内容如下图所示
一行中有四组表,我们获取的数据不仅仅是一个页面的内容,因此我们只能在这里找到统一的规律。最后,我们直接使用简单而粗略的方法var divs=HTML。Cssselect(“table tr”)//直接获取最低表的tr
在获得相应的值后,会遇到另一个问题。无论捕获的数据是读取到控制应用程序控制台还是保存在文本中,中文读取都是一个问号。最后,我们发现这是格式编码的问题。演示中网页的格式编码是UTF-8,scrapysharp捕获的默认格式编码也应该是UTF-8,所以不会有问题,统计局的编码格式是gbk2312。由于请求的捕获数据没有使用正确的编码格式,因此捕获的数据会变得混乱
如前所述,百度搜索基本上是天方的博客文章。类似的问题根本没有解决方案,也找不到scrapysharp的使用文档。最后,在一个边际的文章. 代码如下
到目前为止,web内容的捕获基本上是成功的,因此启动该程序并让它捕获数据
但是,在运行程序的过程中遇到的一个问题是,有时网络不稳定或访问网站太频繁,导致502错误,程序将报告异常。我的解决方案是使用try-catch抓取网页内容。如果不正常,则为内容分配一个空字符串,并让其继续运行,因此没有问题,但是,这不是一个好的解决方案。然而,目前的容量是有限的,所以我们只能先使用它 查看全部
浏览器抓取网页(TianFang-使用ScrapySharp快速从网页中采集数据这里的CSS选择器)
我们需要使用市、区、县居委会对应的区号,所以我们可以在统计局的网页上找到这些数据。我们使用htmlagilitypack和scrapsharp。因为这也是第一次从网页捕获数据,所以我们不熟悉htmlagilitypack和scrapsharp的使用。在此期间,我们遇到了许多问题。这里是一个总结
对于htmlagilitypack和scrapysharp的使用,互联网上有很多演示。然而,看起来他们基本上是同一篇文章,我不知道谁是原作者。如果你把天方的博客放在这里,你就不会复制演示,而是附上一个链接,如果你需要的话,你可以看一看
天方-使用scrapysharp从网页中快速提取采集数据
这里CSS选择器的使用非常简单,就像我们编写CSS来定位HTML元素一样。统计局网站的内容如下图所示
一行中有四组表,我们获取的数据不仅仅是一个页面的内容,因此我们只能在这里找到统一的规律。最后,我们直接使用简单而粗略的方法var divs=HTML。Cssselect(“table tr”)//直接获取最低表的tr
在获得相应的值后,会遇到另一个问题。无论捕获的数据是读取到控制应用程序控制台还是保存在文本中,中文读取都是一个问号。最后,我们发现这是格式编码的问题。演示中网页的格式编码是UTF-8,scrapysharp捕获的默认格式编码也应该是UTF-8,所以不会有问题,统计局的编码格式是gbk2312。由于请求的捕获数据没有使用正确的编码格式,因此捕获的数据会变得混乱
如前所述,百度搜索基本上是天方的博客文章。类似的问题根本没有解决方案,也找不到scrapysharp的使用文档。最后,在一个边际的文章. 代码如下
到目前为止,web内容的捕获基本上是成功的,因此启动该程序并让它捕获数据
但是,在运行程序的过程中遇到的一个问题是,有时网络不稳定或访问网站太频繁,导致502错误,程序将报告异常。我的解决方案是使用try-catch抓取网页内容。如果不正常,则为内容分配一个空字符串,并让其继续运行,因此没有问题,但是,这不是一个好的解决方案。然而,目前的容量是有限的,所以我们只能先使用它
浏览器抓取网页(puppeteergoogle团队出品的puppeteer和浏览器功能)
网站优化 • 优采云 发表了文章 • 0 个评论 • 228 次浏览 • 2021-09-18 04:21
木偶演员
GoogleChrome团队生产的puppeter是一个依靠nodejs和Chrome的自动化测试库。它最大的优点是可以处理网页中的动态内容,如JavaScript,并更好地模拟用户
一些网站反爬虫方法在一些JavaScript/Ajax请求中隐藏了部分内容,这使得直接获取a标记的方法无效。有些网站甚至会设置用户看不见的隐藏元素“陷阱”,脚本触发器被认为是机器。在这种情况下,木偶师的优势就突出了
可实现以下功能:
1.生成页面的截图和PDF
2.抓取spa并生成预渲染内容(即“SSR”)
3.自动表单提交、UI测试、键盘输入等
4.创建最新的自动化测试环境。使用最新的JavaScript和浏览器功能直接在最新版本的chrome中运行测试
5.捕获并跟踪您的网站时间线,以帮助诊断性能问题
开放源代码地址:[]1]
装置
npm i puppeteer
注意:首先安装nodejs并在nodejs文件的根目录下执行(同一级别的NPM文件)
铬将在安装过程中下载,约120m
花了两天(约10小时)的时间探索并绕过了大量的异步坑。作者对木偶演员和舞者有一定的掌握
长照片、抓拍blog文章List:
抓住blog文章
以CSDN博客为例,文章内容需要通过点击“读取全文”获取,这导致只能读取dom的脚本失效
/**
* load blog.csdn.net 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.csdn.net/';
//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; iwindow.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 {
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();
}
}
})();
执行过程
录音机可以在我的官方帐户中查看,屏幕截图如下:
执行结果
文章内容列表:
文章content:
结论
我认为由于nodejs使用JavaScript脚本语言,它当然可以处理web页面的JavaScript内容,但我没有找到合适/高效的库。直到找到木偶师,我才下定决心试水
换句话说,nodejs的异步性确实令人头痛。我已经花了10个小时写了几百行代码
您可以在代码中展开process()方法并使用async.eachseries。我使用的递归方法不是最佳解决方案
事实上,逐个处理是没有效率的。我最初编写了一个异步方法来关闭浏览器:
<p>let tryCloseBrowser = setInterval(function(){
console.log("check if any process running...")
if(countDown 查看全部
浏览器抓取网页(puppeteergoogle团队出品的puppeteer和浏览器功能)
木偶演员
GoogleChrome团队生产的puppeter是一个依靠nodejs和Chrome的自动化测试库。它最大的优点是可以处理网页中的动态内容,如JavaScript,并更好地模拟用户
一些网站反爬虫方法在一些JavaScript/Ajax请求中隐藏了部分内容,这使得直接获取a标记的方法无效。有些网站甚至会设置用户看不见的隐藏元素“陷阱”,脚本触发器被认为是机器。在这种情况下,木偶师的优势就突出了
可实现以下功能:
1.生成页面的截图和PDF
2.抓取spa并生成预渲染内容(即“SSR”)
3.自动表单提交、UI测试、键盘输入等
4.创建最新的自动化测试环境。使用最新的JavaScript和浏览器功能直接在最新版本的chrome中运行测试
5.捕获并跟踪您的网站时间线,以帮助诊断性能问题
开放源代码地址:[]1]
装置
npm i puppeteer
注意:首先安装nodejs并在nodejs文件的根目录下执行(同一级别的NPM文件)
铬将在安装过程中下载,约120m
花了两天(约10小时)的时间探索并绕过了大量的异步坑。作者对木偶演员和舞者有一定的掌握
长照片、抓拍blog文章List:
抓住blog文章
以CSDN博客为例,文章内容需要通过点击“读取全文”获取,这导致只能读取dom的脚本失效
/**
* load blog.csdn.net 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.csdn.net/';
//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; iwindow.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 {
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();
}
}
})();
执行过程
录音机可以在我的官方帐户中查看,屏幕截图如下:
执行结果
文章内容列表:
文章content:
结论
我认为由于nodejs使用JavaScript脚本语言,它当然可以处理web页面的JavaScript内容,但我没有找到合适/高效的库。直到找到木偶师,我才下定决心试水
换句话说,nodejs的异步性确实令人头痛。我已经花了10个小时写了几百行代码
您可以在代码中展开process()方法并使用async.eachseries。我使用的递归方法不是最佳解决方案
事实上,逐个处理是没有效率的。我最初编写了一个异步方法来关闭浏览器:
<p>let tryCloseBrowser = setInterval(function(){
console.log("check if any process running...")
if(countDown
浏览器抓取网页(浏览器上如何渲染出图形数据的文本渲染方式?)
网站优化 • 优采云 发表了文章 • 0 个评论 • 121 次浏览 • 2021-09-17 10:03
浏览器抓取网页数据,我们知道网页上获取数据的方式有http协议的文本,https协议的http请求,post请求等,这三种方式那种更加稳定呢?针对这个问题,我们可以通过页面的webgl加速,webgl实际上是一种通用计算机图形接口(gpu)或webgl浏览器应用接口(svg),目前webgl已成为web及桌面界面开发的标准工具。
其与webgl实现的原理分为三种:原生代码:和java(ie7及更高)一样,以c++、objective-c、swift或java交叉编译,获取数据原生客户端:原生代码,以opengles2.0实现,即使有浏览器提供api接口,渲染服务器也不提供。图形协议:不需要渲染服务器渲染,以image/svg/flash等格式直接输出html内容,用户也可以直接浏览html代码。
接下来我们就尝试探讨一下三种渲染方式在访问时,在浏览器上如何渲染出图形数据,从而达到最终效果。文本渲染通过浏览器来抓取网页的内容时,直接抓取网页数据。网页将传输给flash,从而flash获取该数据并显示出来。对于该行为,涉及两部分的技术,首先是图形应用程序,第二是浏览器。下面我们就分别来看一下,webgl在这两部分技术上都做了哪些工作,他们分别是如何将图形输出到浏览器中的。
1.图形应用程序:可能是graphicsbuilder,或者是c++语言的webgl库。这个是完全出于项目开发考虑,首先项目考虑将脚本逻辑放在对应的模块中,同时通过graphicsbuilder这个脚本库,集成图形绘制能力,graphicsbuilder是一个webgl库,下面我们就介绍其中的一个部分,graphicsbuilder2.1如何传入该图形程序打开浏览器,打开图形控制台输入:webgl-toolbox,然后回车,就会执行webgl图形控制台脚本,然后编译生成graphicsbuilder2.2如何传递数据假设我们通过http协议发送了一个html格式的网页数据,里面包含一个链接,点击这个链接,再点击发送数据。
在urlencode-to-binary中传递:{"this-url":"","actions":[{"type":"minimal","type":"success","data":{"attitude":["90","85","95"],"tightness":"30","left":["22","23","25"],"height":["145","144","166"],"width":["320","640","362"],"min":1135,"max":"3332","offset":["1","2","3"],"onleft":["322","822","912"],"onright":["322","842","833"],"connection。 查看全部
浏览器抓取网页(浏览器上如何渲染出图形数据的文本渲染方式?)
浏览器抓取网页数据,我们知道网页上获取数据的方式有http协议的文本,https协议的http请求,post请求等,这三种方式那种更加稳定呢?针对这个问题,我们可以通过页面的webgl加速,webgl实际上是一种通用计算机图形接口(gpu)或webgl浏览器应用接口(svg),目前webgl已成为web及桌面界面开发的标准工具。
其与webgl实现的原理分为三种:原生代码:和java(ie7及更高)一样,以c++、objective-c、swift或java交叉编译,获取数据原生客户端:原生代码,以opengles2.0实现,即使有浏览器提供api接口,渲染服务器也不提供。图形协议:不需要渲染服务器渲染,以image/svg/flash等格式直接输出html内容,用户也可以直接浏览html代码。
接下来我们就尝试探讨一下三种渲染方式在访问时,在浏览器上如何渲染出图形数据,从而达到最终效果。文本渲染通过浏览器来抓取网页的内容时,直接抓取网页数据。网页将传输给flash,从而flash获取该数据并显示出来。对于该行为,涉及两部分的技术,首先是图形应用程序,第二是浏览器。下面我们就分别来看一下,webgl在这两部分技术上都做了哪些工作,他们分别是如何将图形输出到浏览器中的。
1.图形应用程序:可能是graphicsbuilder,或者是c++语言的webgl库。这个是完全出于项目开发考虑,首先项目考虑将脚本逻辑放在对应的模块中,同时通过graphicsbuilder这个脚本库,集成图形绘制能力,graphicsbuilder是一个webgl库,下面我们就介绍其中的一个部分,graphicsbuilder2.1如何传入该图形程序打开浏览器,打开图形控制台输入:webgl-toolbox,然后回车,就会执行webgl图形控制台脚本,然后编译生成graphicsbuilder2.2如何传递数据假设我们通过http协议发送了一个html格式的网页数据,里面包含一个链接,点击这个链接,再点击发送数据。
在urlencode-to-binary中传递:{"this-url":"","actions":[{"type":"minimal","type":"success","data":{"attitude":["90","85","95"],"tightness":"30","left":["22","23","25"],"height":["145","144","166"],"width":["320","640","362"],"min":1135,"max":"3332","offset":["1","2","3"],"onleft":["322","822","912"],"onright":["322","842","833"],"connection。