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- ...
随机推荐
- springboot 集成mybatis时日志输出
application.properties(yml)中配置的两种方式: 这两种方式的效果是一样的,但是下面一种可以指定某个包下的SQL打印出来,上面这个会全部的都会打印出来.
- Jmeter系列(35)- 使用 ServerAgent 监控服务器
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 前言 做性能测试,监控服务器资源指标是 ...
- Python实用笔记 (27)面向对象高级编程——使用枚举类
枚举类型定义一个class类型,然后,每个常量都是class的一个唯一实例.Python提供了Enum类来实现这个功能: from enum import Enum Month = Enum('Mon ...
- 老板急坏了,公司网站的 HTTPS 过期了
端午出去玩的时候,老板打电话说公司网站的 HTTPS 过期了,访问不了(见下图),要我立马升级一下.可惜我当时没带电脑,无能为力,可把老板急坏了. 没办法,急就先急着,只能等我有电脑了才能搞.点击高级 ...
- numpy模块&pandas模块
目录 numpy模块 pandas模块 numpy模块 import pandas as pd import numpy as np df=pd.Series(np.array(['a','b'])) ...
- 《算法笔记》9.4小节 问题 B: 二叉搜索树
这道题也当做二叉搜索树的建树模板. 这道题其实直接把这颗树建出来后,比较前序序列和中序序列即可,这里我用的数组实现,更好写和查错qwq. code: #include <bits/stdc++. ...
- 使用selenium抓取淘宝信息并存储mongodb
selenium模块 简单小例子 Author:song import pyquery from selenium import webdriver from selenium.common.exce ...
- Tomcat启动流程简析
Tomcat是一款我们平时开发过程中最常用到的Servlet容器.本系列博客会记录Tomcat的整体架构.主要组件.IO线程模型.请求在Tomcat内部的流转过程以及一些Tomcat调优的相关知识. ...
- CSS五种方式实现 Footer 置底
页脚置底(Sticky footer)就是让网页的footer部分始终在浏览器窗口的底部.当网页内容足够长以至超出浏览器可视高度时,页脚会随着内容被推到网页底部:但如果网页内容不够长,置底的页脚就会保 ...
- 理解css中Grid布局,在项目中如何实现grid页面布局
简介 CSS中Grid是一种二维网格式布局方式.我们常规使用table.float.position.inline-block等布局,但它们遗漏了很多功能,例如垂直居中.后来css3中flexbox的 ...