从网页中提取结构化数据:Puppeteer和Cheerio的高级技巧

简介: 在本文中,我们将介绍两个常用的网页数据抓取工具:Puppeteer和Cheerio。Puppeteer是一个基于Node.js的无头浏览器库,它可以模拟浏览器的行为,如打开网页、点击元素、填写表单等。Cheerio是一个基于jQuery的HTML解析库,它可以方便地从HTML文档中提取数据,如选择器、属性、文本等。我们将结合这两个工具,展示如何从网页中提取结构化数据,并给出一些高级技巧,如使用代理IP、处理动态内容、优化性能等。

亿牛云代理

导语

网页数据抓取是一种从网页中提取有用信息的技术,它可以用于各种目的,如数据分析、竞争情报、内容聚合等。然而,网页数据抓取并不是一件容易的事情,因为网页的结构和内容可能会随时变化,而且有些网站会采用反爬虫措施,阻止或限制爬虫的访问。因此,我们需要使用一些高级的技巧,来提高爬虫的效率和稳定性。

概述

在本文中,我们将介绍两个常用的网页数据抓取工具:Puppeteer和Cheerio。Puppeteer是一个基于Node.js的无头浏览器库,它可以模拟浏览器的行为,如打开网页、点击元素、填写表单等。Cheerio是一个基于jQuery的HTML解析库,它可以方便地从HTML文档中提取数据,如选择器、属性、文本等。我们将结合这两个工具,展示如何从网页中提取结构化数据,并给出一些高级技巧,如使用代理IP、处理动态内容、优化性能等。

正文

使用代理IP提高爬虫效果

代理IP是一种隐藏真实IP地址的方法,它可以让爬虫伪装成不同的用户或地区访问网站,从而避免被封禁或限速。使用代理IP的方法有很多,例如使用第三方服务、自建代理池等。在本文中,我们将使用亿牛云爬虫代理作为示例,它提供了稳定、快速、安全的代理IP服务,并支持多种协议和认证方式。

要使用亿牛云爬虫代理,我们需要先注册一个账号,并获取域名、端口、用户名和密码。然后,在Puppeteer中,我们可以通过设置launch方法的args参数,来指定代理IP地址和认证信息。例如:

// 引入puppeteer模块
const puppeteer = require('puppeteer');

// 定义亿牛云 爬虫加强版代理的域名、端口、用户名和密码
const proxyDomain = 'www.16yun.cn';
const proxyPort = '9020';
const proxyUser = '16YUN';
const proxyPass = '16IP';

// 启动无头浏览器,并设置亿牛云代理IP地址和认证信息
const browser = await puppeteer.launch({
   
   
  args: [
    `--proxy-server=${proxyDomain}:${proxyPort}`,
    `--proxy-auth=${proxyUser}:${proxyPass}`
  ]
});

这样,我们就可以通过亿牛云爬虫代理访问任何网站了。

处理动态内容

动态内容是指那些不是在网页加载时就存在的内容,而是通过JavaScript或Ajax等技术在运行时生成或更新的内容。例如,有些网站会使用分页或滚动加载来显示更多数据,或者使用下拉菜单或按钮来切换不同的视图。这些动态内容对于普通的HTML解析器来说是不可见的,因此我们需要使用Puppeteer来模拟浏览器的交互行为,来触发或获取这些内容。

在Puppeteer中,我们可以使用page对象来操作网页。page对象提供了很多方法和事件,来模拟用户的输入和反馈。例如:

  • page.goto(url):打开一个网页
  • page.waitForSelector(selector):等待一个元素出现
  • page.click(selector):点击一个元素
  • page.evaluate(function):在网页中执行一个函数
  • page.on(event, handler):监听一个事件

使用这些方法,我们可以实现很多复杂的交互逻辑,来处理动态内容。例如,假设我们要从一个电商网站中提取商品的名称、价格和评分,但是这些数据是通过滚动加载的,我们可以使用以下代码:

// 引入puppeteer和cheerio模块
const puppeteer = require('puppeteer');
const cheerio = require('cheerio');

// 定义目标网址
const url = 'https://www.amazon.com/s?k=iphone';

// 启动无头浏览器,并设置亿牛云代理IP地址和认证信息
const browser = await puppeteer.launch({
   
   
  args: [
    `--proxy-server=${proxyDomain}:${proxyPort}`,
    `--proxy-auth=${proxyUser}:${proxyPass}`
  ]
});

// 打开一个新的页面
const page = await browser.newPage();

// 打开目标网址
await page.goto(url);

// 定义一个空数组,用于存储提取的数据
let data = [];

// 定义一个循环,用于滚动加载更多数据
while (true) {
   
   
  // 等待商品列表出现
  await page.waitForSelector('.s-result-list');

  // 获取网页的HTML内容
  const html = await page.content();

  // 使用cheerio加载HTML内容,并提取数据
  const $ = cheerio.load(html);
  $('.s-result-item').each((index, element) => {
   
   
    // 获取商品的名称、价格和评分
    const name = $(element).find('.a-size-medium').text().trim();
    const price = $(element).find('.a-price-whole').text().trim();
    const rating = $(element).find('.a-icon-alt').text().trim();

    // 如果数据不为空,就添加到数组中
    if (name && price && rating) {
   
   
      data.push({
   
    name, price, rating });
    }
  });

  // 打印当前提取的数据数量
  console.log(`当前提取了${
     
     data.length}条数据`);

  // 判断是否有下一页的按钮
  const nextButton = await page.$('.a-last a');

  // 如果有下一页的按钮,就点击它,并继续循环
  if (nextButton) {
   
   
    await nextButton.click();
  } else {
   
   
    // 如果没有下一页的按钮,就退出循环
    break;
  }
}

// 关闭无头浏览器
await browser.close();

// 打印最终提取的数据
console.log(data);

这样,我们就可以从动态内容中提取结构化数据了。

优化性能

性能是指爬虫的运行速度和资源消耗。性能优化是指通过一些方法,来提高爬虫的运行效率和稳定性。性能优化的方法有很多,例如:

  • 减少无用的请求:有些网页会加载很多不相关的资源,如图片、视频、广告等,这些资源对于数据抓取来说是没有用的,而且会增加网络流量和内存占用。我们可以通过设置page.setRequestInterception(true)page.on('request', callback)来拦截和过滤这些请求。例如:
// 启用请求拦截
await page.setRequestInterception(true);

// 监听请求事件,并过滤不需要的请求类型
page.on('request', request => {
   
   
  const type = request.resourceType();
  if (type === 'image' || type === 'media' || type === 'font') {
   
   
    request.abort();
  } else {
   
   
    request.continue();
  }
});
  • 并发多个任务:有些时候,我们需要抓取多个网页或多个网站的数据,如果我们按照顺序一个一个地抓取,那么会花费很多时间。我们可以通过使用Promise.all()Promise.map()等方法,来并发多个任务,从而提高爬虫的速度。例如,假设我们要从三个不同的网站中提取新闻标题,我们可以使用以下代码:
// 引入puppeteer和cheerio模块
const puppeteer = require('puppeteer');
const cheerio = require('cheerio');

// 定义三个目标网址
const urls = [
  'https://www.bbc.com/news',
  'https://www.cnn.com',
  'https://www.nytimes.com'
];

// 启动无头浏览器,并设置亿牛云代理IP地址和认证信息
const browser = await puppeteer.launch({
   
   
  args: [
    `--proxy-server=${proxyDomain}:${proxyPort}`,
    `--proxy-auth=${proxyUser}:${proxyPass}`
  ]
});

// 定义一个函数,用于从一个网址中提取新闻标题
const getNewsTitles = async (url) => {
   
   
  // 打开一个新的页面
  const page = await browser.newPage();

  // 打开目标网址
  await page.goto(url);

  // 获取网页的HTML内容
  const html = await page.content();

  // 使用cheerio加载HTML内容,并提取数据
  const $ = cheerio.load(html);
  const titles = [];
  $('h1, h2, h3').each((index, element) => {
   
   
    // 获取新闻标题,并去除空白字符
    const title = $(element).text().trim();

    // 如果标题不为空,就添加到数组中
    if (title) {
   
   
      titles.push(title);
    }
  });

  // 返回提取的数据
  return titles;
};

// 使用Promise.all()并发执行三个任务,并获取结果
const results = await Promise.all(urls.map(getNewsTitles));

// 关闭无头浏览器
await browser.close();

// 打印最终提取的数据
console.log(results);

这样,我们就可以同时从三个网站中提取新闻标题了。

案例

为了更好地理解和应用Puppeteer和Cheerio的高级技巧,我们将以一个具体的案例来进行演示。我们的目标是从豆瓣电影网站中提取最新上映的电影的名称、评分、类型和简介,并保存到一个CSV文件中。

首先,我们需要安装puppeteer、cheerio和csv-writer这三个模块:

npm install puppeteer cheerio csv-writer --save

然后,我们需要编写以下代码:

// 引入puppeteer、cheerio和csv-writer模块
const puppeteer = require('puppeteer');
const cheerio = require('cheerio');
const csvWriter = require('csv-writer');

// 定义目标网址
const url = 'https://movie.douban.com/cinema/nowplaying';

// 启动无头浏览器,并设置亿牛云代理IP地址和认证信息
const browser = await puppeteer.launch({
   
   
  args: [
    `--proxy-server=${proxyDomain}:${proxyPort}`,
    `--proxy-auth=${proxyUser}:${proxyPass}`
  ]
});

// 打开一个新的页面
const page = await browser.newPage();

// 打开目标网址
await page.goto(url);

// 获取网页的HTML内容
const html = await page.content();

// 使用cheerio加载HTML内容,并提取数据
const $ = cheerio.load(html);
const data = [];
$('#nowplaying .list-item').each((index, element) => {
   
   
  // 获取电影的名称、评分、类型和简介
  const name = $(element).data('title');
  const rating = $(element).data('score');
  const genre = $(element).data('category');
  const summary = $(element).find('.stitle a').attr('title');

  // 如果数据不为空,就添加到数组中
  if (name && rating && genre && summary) {
   
   
    data.push({
   
    name, rating, genre, summary });
  }
});

// 关闭无头浏览器
await browser.close();

// 定义CSV文件的列名和路径
const columns = [
  {
   
    id: 'name', title: '名称' },
  {
   
    id: 'rating', title: '评分' },
  {
   
    id: 'genre', title: '类型' },
  {
   
    id: 'summary', title: '简介' }
];
const path = './movies.csv';

// 创建一个CSV文件写入器,并写入数据
const writer = csvWriter.createObjectCsvWriter({
   
    path, columns });
await writer.writeRecords(data);

// 打印完成的提示
console.log('数据已保存到movies.csv文件中');

最后,我们可以运行以下命令,来执行我们的代码:

node index.js

这样,我们就可以从豆瓣电影网站中提取最新上映的电影的数据,并保存到一个CSV文件中了。

结语

在本文中,我们介绍了如何使用Puppeteer和Cheerio来从网页中提取结构化数据,并给出了一些高级技巧,如使用代理IP、处理动态内容、优化性能等。我们还以一个具体的案例来进行演示,从豆瓣电影网站中提取最新上映的电影的数据,并保存到一个CSV文件中。我们希望这些技巧和案例能够对您有所启发和帮助,让您能够更好地利用网页数据抓取的技术,来实现您的目标和需求。

相关文章
|
Web App开发 前端开发
ZLMediaKit解决webrtc前端replaceTrack断流问题
ZLMediaKit解决webrtc前端replaceTrack断流问题
|
7月前
|
传感器 算法 物联网
室内定位无线技术的分类和原理全解析(一)
室内定位无线技术通过射频、声波、光信号等解决卫星信号无法覆盖的盲区,实现人员、物资精准定位。主流技术分射频、声波、光学及新兴四大类,涵盖蓝牙、UWB、Wi-Fi、红外、可见光、毫米波等,适用于工业、医疗、园区等多场景,各具精度、成本与部署优势。
|
存储 人工智能 运维
企业级MLOps落地:基于PAI-Studio构建自动化模型迭代流水线
本文深入解析MLOps落地的核心挑战与解决方案,涵盖技术断层分析、PAI-Studio平台选型、自动化流水线设计及实战构建,全面提升模型迭代效率与稳定性。
636 6
|
11月前
|
机器学习/深度学习 监控 算法
摊位货摊自动识别与监控系统识别系统开箱即用教程 (YOLOv8)| 完整源码与部署教程
本项目展示了如何通过 YOLOv8 深度学习模型与 PyQt5 图形界面结合,开发一个 摊位货摊自动识别与监控系统。该系统能够高效地检测摊位上的商品,并对周围的行为进行实时监控,为摊位管理带来极大的便利。系统支持多种输入方式,如图像、视频和摄像头,并具备异常行为检测和报警功能。
摊位货摊自动识别与监控系统识别系统开箱即用教程 (YOLOv8)| 完整源码与部署教程
|
安全 虚拟化 Windows
Windows Server 2016 中文版、英文版下载 (2025 年 2 月更新)
Windows Server 2016 中文版、英文版下载 (2025 年 2 月更新)
594 17
Windows Server 2016 中文版、英文版下载 (2025 年 2 月更新)
|
存储 弹性计算 关系型数据库
【赵渝强老师】达梦数据库的产品系列
达梦数据库是达梦公司推出的新一代自研数据库,融合分布式、弹性计算与云计算优势,支持超大规模并发事务处理和HTAP混合业务。产品体系包括DM8、DMDSC、DM DataWatch、DMMPP和DMRWC,分别适用于通用关系型数据库、共享存储集群、数据守护集群、大规模数据分析及读写分离场景,满足不同需求并保障高可用性和安全性。
792 36
|
jenkins 持续交付 开发工具
除了 Gitee,还有哪些代码托管平台支持 Webhook?
除了 Gitee,还有哪些代码托管平台支持 Webhook?
|
缓存 关系型数据库 MySQL
服务器磁盘爆满?别慌,教你轻松清理!
服务器磁盘空间告急?别慌!本文将教你如何快速识别并清理占用大量磁盘空间的文件和目录,优化日志文件,释放磁盘空间,恢复系统正常运行。适合服务器管理员和网站运营者。
2297 0
 服务器磁盘爆满?别慌,教你轻松清理!
|
人工智能 监控 测试技术
阿里云磐久服务器稳定性实践之路
阿里云服务器质量智能管理体系聚焦自研服务器硬件层面的极致优化,应对高并发交付、短稳定性周期、早问题发现和快修复四大挑战。通过“三个重构”(质量标准、开发流程、交付模式)、“六个归一”(架构、硬件、软件、测试、部件、制造)策略,实现芯片、整机和云同步发布,确保快速稳定上量。此外,全场景测试体系与智能预警、分析、修复系统协同工作,保障服务器在萌芽阶段发现问题并及时解决,提升整体质量水平。未来,阿里云将继续深化大数据驱动的质量管理,推动服务器行业硬件质量的持续进步。
|
编解码 人工智能 算法
国家扶持超高清产业背景下:视频云AIGC的超高清技术实践
本次分享由阿里云视频云高级产品解决方案架构师陈震主讲,聚焦国家扶持超高清产业背景下,视频云AIGC的超高清技术实践。内容涵盖超高清产业发展趋势与挑战、阿里视频云的应对方案及应用案例。通过全链路超高清解决方案,结合AI、云计算等技术,提供从内容生产、传输到播放的完整支持,助力行业应对超高清视频带来的技术与市场挑战。
769 0