本篇文章针对大家熟知的技术站点作为目标进行技术实践。

确定需求

  访问目标网站并按照筛选条件(关键词、日期、作者)进行检索并获取返回数据中的目标数据。进行技术拆分如下:

  1. 打开目标网站
  2. 找到输入框元素输入关键词,找到日期元素设置日期,找到搜索按钮触发搜索动作
  3. 解析搜索返回的html元素构造目标数据
  4. 将目标数据保存

编写代码

'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的能力,下面我也总结一下工作中和自己项目的实际情况。

  1. 上述例子还不能算是一个完整的应用,根据主要业务分析实际应用大概是这个样子: 爬虫的主要业务变化部分有目标站点、筛选条件、站点操作、数据解析、数据落地,这些都可以通过代码搞定,也就是代码是变化的,所以一个可用的爬虫的应用是代码是可动态调整的,根据上面的动态点将一个爬虫业务抽象成一个Task,
  • 它要具备一个参数输入界面(动态输入目标站点、筛选条件等脚本所需参数),每个task的业务不一样,脚本参数不一样,就需要一个动态表单可配置脚本所需参数(Ant design搞一个也够用了);
  • 站点操作会根据实际情况而希望能够动态调整脚本代码,那就引入一个在线的vscode编辑器(实际开发中通常都是测试好的脚本才会写进去,这个地方引入有些牵强,主要是线上发现一些小bug需要快速解决);
  • 数据解析完了后需要落地,这包括保存到本地、推到api接口、或是下载文件成功推送标识等皆可动态参数和脚本实现;
  1. Task主要流程还有一个重要的点就是触发需要一个定时任务方便用户设置各种周期性的需求,不管是考虑用户需求还是躲避爬虫频率限制都很有必要。
  2. Task主要流程完成后还有很重要的基础设施:
  • 应用快速部署,当然要用到docker了。因为puppeteer其实是依赖了Chromium的能力,所以你需要在容器里部署一套可运行的chromium,这里面牵扯到字体、环境问题等麻烦事情,这里我推荐一个使用的镜像browserless/chrome,这个镜像大家可以根据自己需求定制,视频中的界面演示即FullHead,容器环境往往不是完整的操作系统(应该没人用完整的windows环境吧)而是尽量小的linux版本(我本人使用的是egg引入puppeteer),那么就不可能有界面,即无法实现FullHead,FullHead可以帮我们规避一些站点(部分站点检测手段比较强)的反爬手段,这里使用的是xvfb实现了FullHead。
  • 网络检测,无论是切换容器网络还是在应用中使用ip代理我都没搞过就不说了。分布式爬虫我目前没实现所以这里就不说了。
  1. 实际使用中遇到的一些问题,资讯站渲染的比较随意,解析比较复杂,有些数据只是展示而无固定标签或规律展示,puppeteer的元素选择器有css和xpath,但是这个和大家平常用jquery不太一样,最好去看看标准,它的xpath解析就不完整(比如string(.),因为puppeteer要包返回装类型所以就完蛋了,我提了issue,答复目前也只能遍历了,或者有谁知道可以提醒我下)。网络问题,访问时渲染有时候会超时这个要自己根据需求搞了。

大致就到这吧。

Puppeteer爬虫实战(三)的更多相关文章

  1. Python爬虫实战三之实现山东大学无线网络掉线自动重连

    综述 最近山大软件园校区QLSC_STU无线网掉线掉的厉害,连上之后平均十分钟左右掉线一次,很是让人心烦,还能不能愉快地上自习了?能忍吗?反正我是不能忍了,嗯,自己动手,丰衣足食!写个程序解决掉它! ...

  2. Puppeteer爬虫实战(一)

    Puppeteer 爬虫技术实践 信息简介 Puppeteer是Chrome开发团队发布的一个通过Chrome DevTool Protocol来控制浏览器Chrome(下文若无显式称呼Chromiu ...

  3. Python爬虫实战三之爬取嗅事百科段子

    一.前言 俗话说,上班时间是公司的,下班了时间才是自己的.搞点事情,写个爬虫程序,每天定期爬取点段子,看着自己爬的段子,也是一种乐趣. 二.Python爬取嗅事百科段子 1.确定爬取的目标网页 首先我 ...

  4. Python网络爬虫实战(三)照片定位与B站弹幕

    之前两篇已经说完了如何爬取网页以及如何解析其中的数据,那么今天我们就可以开始第一次实战了. 这篇实战包含两个内容. * 利用爬虫调用Api来解析照片的拍摄位置 * 利用爬虫爬取Bilibili视频中的 ...

  5. 爬虫实战(三) 用Python爬取拉勾网

    目录 0.前言 1.初始化 2.爬取数据 3.保存数据 4.数据可视化 5.大功告成 0.前言 最近,博主面临着选方向的困难(唉,选择困难症患者 >﹏<),所以希望了解一下目前不同岗位的就 ...

  6. 自学Python十 爬虫实战三(美女福利续)

    我又来送福利啦!!!不同于上篇文章,这次我们的爬虫采用了多线程,一直以来被所谓的分布式  多线程  爬虫 给唬的怕怕的.今天就来一发多线程爬虫吧,还能看妹子图,想想就觉得很激动!!! 依然是流程解释: ...

  7. Puppeteer爬虫实战(二)

    连接浏览器 上一篇说到了Puppeteer本质是使用了Chrome Devtools协议控制浏览器,本篇就说说连接方式. 常规Hook浏览器 此方式其实就是需要一个浏览器可执行文件(不同平台需要下载对 ...

  8. python网络爬虫实战PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书

    点击获取提取码:vg1y python网络爬虫实战帮助读者学习Python并开发出符合自己要求的网络爬虫.网络爬虫,又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动地抓取互联网信息的程序或者脚 ...

  9. 第三百三十节,web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解

    第三百三十节,web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解 封装模块 #!/usr/bin/env python # -*- coding: utf- ...

随机推荐

  1. springcloud2.0 添加配置中心遇到的坑

    新手入门,在springcloud 配置config的时候遇到了几个比较烦的坑 先说1.5x版本的一些配置吧 首先是端点暴露的方式 management: security: enabled: fal ...

  2. IDEA 使用jebel热部署插件启动失败

    在使用Jebel热部署插件开发springmvc时,启动会出现内存溢出错误.可在配置Tomcat时增加JVM参数解决. -Xms768m -Xmx768m -XX:PermSize=64M -XX:M ...

  3. 基于TCP与UDP协议的socket通信

    基于TCP与UDP协议的socket通信 C/S架构与初识socket 在开始socket介绍之前,得先知道一个Client端/服务端架构,也就是 C/S 架构,互联网中处处充满了 C/S 架构(Cl ...

  4. javamelody对Java Application进行监控

    前面写过对于webapp,用javamelody来监控.分析性能是挺方便的:那要对普通的java应用进行监控,只需要在应用上启动一个嵌入式web容器就可以了. javamelody里面的war包就用了 ...

  5. vs2013, EF6.0.0.0 使用Migrations来更新数据库时报错

    1.vs中,程序包管理器控制台 2.执行,Enable-Migrations 报错: Migrations have already been enabled in project 'dd'. To ...

  6. .NET 开源项目 StreamJsonRpc 介绍

    StreamJsonRpc 是一个实现了 JSON-RPC 通信协议的开源 .NET 库,在介绍 StreamJsonRpc 之前,我们先来了解一下 JSON-RPC. JSON-RPC 介绍 JSO ...

  7. CSS3 clip-path 用法介绍

    一.基本概念 刷新 QQ 空间动态时,发现一则广告,随着用户上下滑动动态列表,就会自动切换广告图片,这样的效果对移动端本就不大的屏幕来说,无疑是很精妙的考虑,这样的效果是怎么实现的呢? 你可以点击这里 ...

  8. elasticsearch 单节点搭建与爬坑记录

    elasticsearch 单节点搭建与爬坑记录   prepare   虚拟机或者云服务器(这里用的是阿里云ECS) linux---centos7 安装完毕的jdk 相应的安装包(在https:/ ...

  9. 区间dp(能量项链)

    [题目大意] 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记 ...

  10. P5676 [GZOI2017]小z玩游戏 Tarjan+优化建图

    题目描述 分析 一开始看到这道题,首先想到的就是建好边后跑一个Tarjan缩点,将siz大于1的节点统计一下,输出结果 Tarjan非常显然易得,关键就是怎么建边 比较好想的一种思路就是枚举每一个兴奋 ...