Puppeteer爬虫实战(三)
本篇文章针对大家熟知的技术站点作为目标进行技术实践。
确定需求
访问目标网站并按照筛选条件(关键词、日期、作者)进行检索并获取返回数据中的目标数据。进行技术拆分如下:
- 打开目标网站
- 找到输入框元素输入关键词,找到日期元素设置日期,找到搜索按钮触发搜索动作
- 解析搜索返回的html元素构造目标数据
- 将目标数据保存
编写代码
'use strict';
const puppeteer = require('puppeteer');
const csv = require('fast-csv');
const fs = require('fs');
(async () => {
const startUrl = 'https://www.infoq.cn/';
const keyWord = 'CQRS';
const browser = await puppeteer.launch({
slowMo: 100, // 放慢速度
headless: false, // 是否有头
defaultViewport: {// 界面设置
width: 1820,
height: 1080,
},
ignoreHTTPSErrors: false, // 忽略 https 报错
args: ['--start-maximized', '--no-sandbox', '--disable-setuid-sandbox'],
});
const page = await browser.newPage();
await page.goto(startUrl).catch(error => console.log(error));
await page.waitFor(1 * 1000);
await page.click('.search,.iconfont');
await page.type('.search-input', keyWord, { delay: 100 });
const newPagePromise = new Promise(x => browser.once('targetcreated', target => x(target.page())));
await page.click('.search,.iconfont');
const targetPage = await newPagePromise;
const dataCount = await targetPage.$eval('.search-body-main-tips span', el => el && el.innerHTML).catch(error => console.error(error));
if (dataCount && dataCount > 0) {
const dataEle = await targetPage.$$('.search-item');
console.log(dataEle.length);
const stream = fs.createWriteStream('infoq.csv');
const csvStream = csv.format({ headers: true });
csvStream.pipe(stream).on('end', process.exit);
for (let index = 0; index < dataEle.length; index++) {
const element = dataEle[index];
const title = await element.$eval('a', el => el && el.innerHTML).catch(error => console.error(error))
const desc = await element.$eval('.desc', el => el && el.innerHTML).catch(error => console.error(error))
csvStream.write({
标题: title || '',
摘要: desc || '',
});
}
csvStream.end(() => { console.log('写入完毕'); });
}
await targetPage.screenshot({ path: 'infoq.png' });
await browser.close();
})();
具体的如下
总结
上面的例子还是比较简单的,站点本身是资讯站(其实有搜索接口根本不需要解析html),例子是一个简单的爬虫流程,方便了解puppeteer的能力,下面我也总结一下工作中和自己项目的实际情况。
- 上述例子还不能算是一个完整的应用,根据主要业务分析实际应用大概是这个样子: 爬虫的主要业务变化部分有目标站点、筛选条件、站点操作、数据解析、数据落地,这些都可以通过代码搞定,也就是代码是变化的,所以一个可用的爬虫的应用是代码是可动态调整的,根据上面的动态点将一个爬虫业务抽象成一个Task,
- 它要具备一个参数输入界面(动态输入目标站点、筛选条件等脚本所需参数),每个task的业务不一样,脚本参数不一样,就需要一个动态表单可配置脚本所需参数(Ant design搞一个也够用了);
- 站点操作会根据实际情况而希望能够动态调整脚本代码,那就引入一个在线的vscode编辑器(实际开发中通常都是测试好的脚本才会写进去,这个地方引入有些牵强,主要是线上发现一些小bug需要快速解决);
- 数据解析完了后需要落地,这包括保存到本地、推到api接口、或是下载文件成功推送标识等皆可动态参数和脚本实现;
- Task主要流程还有一个重要的点就是触发需要一个定时任务方便用户设置各种周期性的需求,不管是考虑用户需求还是躲避爬虫频率限制都很有必要。
- Task主要流程完成后还有很重要的基础设施:
- 应用快速部署,当然要用到docker了。因为puppeteer其实是依赖了Chromium的能力,所以你需要在容器里部署一套可运行的chromium,这里面牵扯到字体、环境问题等麻烦事情,这里我推荐一个使用的镜像browserless/chrome,这个镜像大家可以根据自己需求定制,视频中的界面演示即FullHead,容器环境往往不是完整的操作系统(应该没人用完整的windows环境吧)而是尽量小的linux版本(我本人使用的是egg引入puppeteer),那么就不可能有界面,即无法实现FullHead,FullHead可以帮我们规避一些站点(部分站点检测手段比较强)的反爬手段,这里使用的是xvfb实现了FullHead。
- 网络检测,无论是切换容器网络还是在应用中使用ip代理我都没搞过就不说了。分布式爬虫我目前没实现所以这里就不说了。
- 实际使用中遇到的一些问题,资讯站渲染的比较随意,解析比较复杂,有些数据只是展示而无固定标签或规律展示,puppeteer的元素选择器有css和xpath,但是这个和大家平常用jquery不太一样,最好去看看标准,它的xpath解析就不完整(比如string(.),因为puppeteer要包返回装类型所以就完蛋了,我提了issue,答复目前也只能遍历了,或者有谁知道可以提醒我下)。网络问题,访问时渲染有时候会超时这个要自己根据需求搞了。
大致就到这吧。
Puppeteer爬虫实战(三)的更多相关文章
- Python爬虫实战三之实现山东大学无线网络掉线自动重连
综述 最近山大软件园校区QLSC_STU无线网掉线掉的厉害,连上之后平均十分钟左右掉线一次,很是让人心烦,还能不能愉快地上自习了?能忍吗?反正我是不能忍了,嗯,自己动手,丰衣足食!写个程序解决掉它! ...
- Puppeteer爬虫实战(一)
Puppeteer 爬虫技术实践 信息简介 Puppeteer是Chrome开发团队发布的一个通过Chrome DevTool Protocol来控制浏览器Chrome(下文若无显式称呼Chromiu ...
- Python爬虫实战三之爬取嗅事百科段子
一.前言 俗话说,上班时间是公司的,下班了时间才是自己的.搞点事情,写个爬虫程序,每天定期爬取点段子,看着自己爬的段子,也是一种乐趣. 二.Python爬取嗅事百科段子 1.确定爬取的目标网页 首先我 ...
- Python网络爬虫实战(三)照片定位与B站弹幕
之前两篇已经说完了如何爬取网页以及如何解析其中的数据,那么今天我们就可以开始第一次实战了. 这篇实战包含两个内容. * 利用爬虫调用Api来解析照片的拍摄位置 * 利用爬虫爬取Bilibili视频中的 ...
- 爬虫实战(三) 用Python爬取拉勾网
目录 0.前言 1.初始化 2.爬取数据 3.保存数据 4.数据可视化 5.大功告成 0.前言 最近,博主面临着选方向的困难(唉,选择困难症患者 >﹏<),所以希望了解一下目前不同岗位的就 ...
- 自学Python十 爬虫实战三(美女福利续)
我又来送福利啦!!!不同于上篇文章,这次我们的爬虫采用了多线程,一直以来被所谓的分布式 多线程 爬虫 给唬的怕怕的.今天就来一发多线程爬虫吧,还能看妹子图,想想就觉得很激动!!! 依然是流程解释: ...
- Puppeteer爬虫实战(二)
连接浏览器 上一篇说到了Puppeteer本质是使用了Chrome Devtools协议控制浏览器,本篇就说说连接方式. 常规Hook浏览器 此方式其实就是需要一个浏览器可执行文件(不同平台需要下载对 ...
- python网络爬虫实战PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书
点击获取提取码:vg1y python网络爬虫实战帮助读者学习Python并开发出符合自己要求的网络爬虫.网络爬虫,又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动地抓取互联网信息的程序或者脚 ...
- 第三百三十节,web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解
第三百三十节,web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解 封装模块 #!/usr/bin/env python # -*- coding: utf- ...
随机推荐
- Docker图形界面管理
之前都是使用命令行进行Docker的管理,这里简单介绍一下Docker的图形界面管理.之所以说简单介绍,是因为在生产环境都是集群,很少使用图形界面管理单台Docker主机,所以就演示记录一下,在个人测 ...
- 入门大数据---Flink学习总括
第一节 初识 Flink 在数据激增的时代,催生出了一批计算框架.最早期比较流行的有MapReduce,然后有Spark,直到现在越来越多的公司采用Flink处理.Flink相对前两个框架真正做到了高 ...
- Python基础语法一
所有内容都在代码上,有相关代码注释 # #代表注释 # 区分大小写.以回车换行结束 # 多行编写可以使用反斜杠 \ # 缩进代表一个代码块 #数值 #int类型可以使用下划线分割 c=123_456_ ...
- java.math.BigDecimal转换double double转换java.math.BigDecimal
有方法 java.math.BigDecimal.doubleValue() BigDecimal a = new BigDecimal(1000);return a.doubleValue(); p ...
- [源码解析]Oozie来龙去脉之提交任务
[源码解析]Oozie来龙去脉之提交任务 0x00 摘要 Oozie是由Cloudera公司贡献给Apache的基于工作流引擎的开源框架,是Hadoop平台的开源的工作流调度引擎,用来管理Hadoop ...
- 版本管理工具(git)
Git是一个开源的分布式版本控制系统 工作区: 电脑目录中,git_test文件夹就是一个工作区. 版本库: 在进行git操作的时候,会生成一个隐藏目录.git,这是git的版本库,其中stage(或 ...
- (私人收藏)2019科协WER解决方案
2019科协WER解决方案 含地图,解决程序,详细规则,搭建方案EV3;乐高;机器人比赛;能力风暴;WER https://pan.baidu.com/s/16sdFmM49bPijYw55i8ox1 ...
- tidyverse|数据分析常规操作-分组汇总(sumamrise+group_by)
| 本文首发于 “生信补给站” https://mp.weixin.qq.com/s/tQt0ezYJj3H7x3aWZmKVEQ 使用tidyverse进行简单的数据处理: 盘一盘Tidyverse ...
- NPOI升级版本问题
最近做了一个导出Word的功能,需要样式与排版果断选择了NPOI,本以为支持Excel很好,支持Word应该也不会错吧,万万没想到还是挣扎了小一星期. 我的项目是一个13年项目,NPOI版本还很旧,我 ...
- Dynamics CRM Data Encrytion error
Dynamics CRM有两个Database,一个Content DB——xxxx_MSCRM,一个Config DB——MSCRM_CONFIG. 当Content DB从其他环境Restore回 ...