使用 Cheerio 和 Node.js 进行网络搜刮 2024

Web scraping 是一种强大的技术,用于从网站提取数据,广泛应用于数据分析、市场研究和内容聚合。截至2024年,利用 Cheerio 和 Node.js 进行 web scraping 仍然是一种流行且高效的方法。本文将深入探讨使用 Cheerio 和 Node.js 进行 web scraping 的过程,提供全面的指南和实用示例。

目录

  • Cheerio是什么?
  • 前提条件
  • 项目设置
  • Cheerio的选择器API
  • 编写抓取脚本
  • 运行脚本
  • 使用Cheerio进行网页抓取的挑战
  • 处理网页抓取中的CAPTCHA
  • 处理动态页面
  • 结论

Cheerio是什么?

Cheerio是一个快速、灵活、轻量的jQuery实现,专为服务器端应用设计。它允许开发人员使用熟悉的jQuery语法在Node.js环境中解析和操作HTML文档。与基于浏览器的工具不同,Cheerio不执行实际的网页渲染,而是直接操作HTML字符串,使其在许多抓取任务中异常高效。顺便说一下,Puppeteer 是一个很好的Cheerio抓取替代方案。

前提条件

在深入代码之前,请确保您的系统上已安装Node.js和npm(Node Package Manager)。如果尚未安装,您可以从Node.js官方网站下载并安装。

项目设置

第一步:创建新项目目录

首先,为您的项目创建一个新目录并将其初始化为一个Node.js项目:

mkdir web-scraping
cd web-scraping
npm init -y

-y标志会自动回答所有提示,设置一个默认的package.json文件。

第二步:安装依赖项

接下来,安装必要的依赖项,包括用于发出HTTP请求的axios和用于解析HTML的cheerio

npm install axios cheerio

Cheerio的选择器API

Cheerio是一个快速、灵活和轻量的核心jQuery实现,专为服务器设计。它允许您在Node.js环境中使用jQuery样式的语法来操作HTML文档。

以下是Cheerio选择器API的详细说明和代码示例:

  1. 加载HTML文档

    const cheerio = require('cheerio');
    const html = `
      <html>
        <head>
          <title>Example</title>
        </head>
        <body>
          <h1 class="title">Hello, world!</h1>
          <div id="content">
            <p>This is a paragraph.</p>
            <a href="https://example.com">Link</a>
          </div>
        </body>
      </html>
    `;
    const $ = cheerio.load(html);
    
  2. 选择元素

    • 元素选择器

      const h1 = $('h1'); // 选择所有<h1>元素
      console.log(h1.text()); // 输出:Hello, world!
      
    • 类选择器

      const title = $('.title'); // 选择class="title"的元素
      console.log(title.text()); // 输出:Hello, world!
      
    • ID选择器

      const content = $('#content'); // 选择id="content"的元素
      console.log(content.html()); // 输出:<p>This is a paragraph.</p><a href="https://example.com">Link</a>
      
    • 属性选择器

      const link = $('a[href="https://example.com"]'); // 选择具有特定href属性的<a>元素
      console.log(link.text()); // 输出:Link
      
  3. 遍历和操作元素

    • 遍历元素

      $('p').each((index, element) => {
        console.log($(element).text()); // 输出每个<p>元素的文本内容
      });
      
    • 修改元素内容

      $('h1.title').text('New Title'); // 修改<h1>元素的文本内容
      console.log($('h1.title').text()); // 输出:New Title
      
    • 添加和删除元素

      $('#content').append('<p>Another paragraph.</p>'); // 在#content中添加一个新的<p>元素
      console.log($('#content').html()); // 输出:<p>This is a paragraph.</p><a href="https://example.com">Link</a><p>Another paragraph.</p>
      
      $('a').remove(); // 删除所有<a>元素
      console.log($('#content').html()); // 输出:<p>This is a paragraph.</p><p>Another paragraph.</p>
      

这些示例展示了如何使用Cheerio的选择器API在Node.js环境中选择、遍历和操作HTML元素,类似于jQuery。

编写抓取脚本

在您的项目目录中创建一个名为scraper.js的文件。该文件将包含从目标网站抓取数据的脚本。将以下代码添加到scraper.js中:

const axios = require('axios');
const cheerio = require('cheerio');

// 目标URL
const url = 'https://example.com';

async function fetchData() {
  try {
    // 发出HTTP请求以获取HTML内容
    const { data } = await axios.get(url);
    // 将HTML文档加载到Cheerio中
    const $ = cheerio.load(data);

    // 从HTML中提取数据
    const title = $('title').text();
    const headings = [];
    $('h1, h2, h3').each((index, element) => {
      headings.push($(element).text());
    });

    // 输出提取的数据
    console.log('Title:', title);
    console.log('Headings:', headings);
  } catch (error) {
    console.error('Error fetching data:', error);
  }
}

fetchData();

代码解释

  1. 导入模块:脚本首先导入axioscheerio模块。
  2. 定义目标URL:定义要抓取的目标网站的URL。
  3. 获取数据fetchData函数使用axios发出HTTP GET请求到目标URL。响应数据(HTML内容)随后加载到Cheerio中。
  4. 解析HTML:使用Cheerio的jQuery样式语法,脚本提取<title>标签和所有<h1><h2><h3>标签的内容。
  5. 输出结果:提取的数据记录在控制台中。

运行脚本

要执行抓取脚本,请在终端中运行以下命令:

node scraper.js

如果一切设置正确,您应该会在控制台中看到抓取到的网页标题和所有标题标签的内容。

使用Cheerio进行网页抓取的挑战

虽然Cheerio在网页抓取方面具有许多优势,但它也存在一些开发人员可能遇到的挑战:

  1. 动态网站和JavaScript:Cheerio的一大挑战是处理依赖JavaScript的动态网站。现代网站通常使用JavaScript在初始页面加载后动态加载内容。由于Cheerio解析的是静态HTML,它可能无法捕获动态生成的内容,这会限制抓取的效果。

  2. 反抓取措施:网站采用各种反抓取技术来阻止自动化数据提取:

    • CAPTCHA:主要问题是设计用来区分人类和机器人用户的CAPTCHA,要求用户完成图像识别或文本输入等任务。
    • IP封锁:网站可能会封锁与抓取活动相关的IP地址,以防止过多的请求。
    • 用户代理检测:检测非标准或可疑的用户代理有助于网站识别和封锁抓取程序。
    • 动态网页:使用动态JavaScript内容生成的网站可能会带来挑战,因为内容可能无法通过Cheerio的静态解析直接访问。

作为网页抓取开发人员,了解这些挑战对于有效地解决它们至关重要。针对这些问题有许多缓解解决方案的策略,在接下来的部分中,我们将解释如何通过解决验证码问题和处理动态页面来解决抓取中的两大问题:

处理网页抓取中的CAPTCHA

CAPTCHA在网页抓取中构成了重大挑战,因为它们旨在区分人类和机器人。当遇到时,您的抓取脚本必须高效地解决它们,以继续进行抓取任务。对于可扩展的网页抓取工作,像CapSolver这样的解决方案提供高精度和快速的CAPTCHA解决能力。

集成CAPTCHA解决方案

各种CAPTCHA解决服务可以集成到您的抓取脚本中。这里,我们重点介绍CapSolver:

步骤1:注册CapSolver

首先,导航到CapSolver用户面板并注册您的账户。

步骤2:获取您的API密钥

注册后,从主页面板中获取您的API密钥。

CapSolver API Key

CapSolver集成示例代码

将CapSolver集成到您的网页抓取或自动化项目中非常简单。以下是一个使用CapSolver API的Python示例:

# pip install requests
import requests
import time

# TODO: set your config
api_key = "YOUR_API_KEY"  # your CapSolver API key
site_key = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"  # target site's reCAPTCHA site key
site_url = ""  # URL of your target site


def solve_captcha():
    payload = {
        "clientKey": api_key,
        "task": {
            "type": 'ReCaptchaV2TaskProxyLess',
            "websiteKey": site_key,
            "websiteURL": site_url
        }
    }
    res = requests.post("https://api.capsolver.com/createTask", json=payload)
    resp = res.json()
    task_id = resp.get("taskId")
    if not task_id:
        print("Failed to create task:", res.text)
        return
    print(f"Got taskId: {task_id} / Retrieving result...")

    while True:
        time.sleep(3)  # delay
        payload = {"clientKey": api_key, "taskId": task_id}
        res = requests.post("https://api.capsolver.com/getTaskResult", json=payload)
        resp = res.json()
        status = resp.get("status")
        if status == "ready":
            return resp.get("solution", {}).get('gRecaptchaResponse')
        if status == "failed" or resp.get("errorId"):
            print("Solution failed! Response:", res.text)
            return


captcha_token = solve_captcha()
print(captcha_token)

此脚本演示了如何利用CapSolver的API来解决reCAPTCHA挑战。将此类解决方案集成到您的抓取项目中,通过自动化CAPTCHA解决,提高了效率,简化了数据提取过程。

处理动态页面

对于通过JavaScript加载动态内容的网页,您可能需要使用像puppeteer这样的无头浏览器。Puppeteer可以模拟真实用户浏览网页,从而允许您抓取只有在JavaScript执行后才出现的内容。

Puppeteer示例

以下是如何将Puppeteer与Cheerio结合使用的简短示例:

const puppeteer = require('puppeteer');
const cheerio = require('cheerio');

async function fetchData() {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');

  const content = await page.content();
  const $ = cheerio.load(content);

  const title = $('title').text();
  const headings = [];
  $('h1, h2, h3').each((index, element) => {
    headings.push($(element).text());
  });

  console.log('Title:', title);
  console.log('Headings:', headings);

  await browser.close();
}

fetchData();

此脚本启动一个无头浏览器,导航到目标URL,并在JavaScript执行后获取HTML内容。然后,它使用Cheerio解析HTML并提取所需数据。

结论

使用Cheerio和Node.js进行网页抓取是提取网站数据的强大组合。Cheerio的jQuery样式语法使得导航和操作HTML文档变得容易,而Node.js提供了处理HTTP请求和处理数据的强大环境。

然而,开发人员必须意识到动态内容和反抓取措施(如CAPTCHA)带来的挑战。集成像CapSolver这样的解决方案可以帮助克服这些障碍,确保您的抓取脚本保持高效和可靠。

希望这篇文章能帮助您在2024年开始网页抓取,并为您的项目提供有用的数据!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/716631.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机械师电脑文件丢失怎么办?6个恢复方法,希望能帮到您

机械师电脑作为高性能的计算机品牌&#xff0c;受到众多用户的青睐。然而&#xff0c;即便是品质卓越的电脑&#xff0c;也难免会遇到文件丢失的困扰。无论是由于误操作、系统故障还是硬盘损坏&#xff0c;文件丢失都可能给用户带来不小的麻烦。当您发现机械师电脑上的文件突然…

win10能用微信、QQ,不能打开网页

今天上班&#xff0c;打开电脑&#xff0c;突然遇到一个问题&#xff0c;发现QQ、微信可以登录&#xff0c;但是任何网页都打不开&#xff0c;尝试了重启电脑和路由器都不行&#xff0c;最终解决了电脑可以访问网页的问题&#xff0c;步骤如下&#xff1a; 1、打开电脑的网络设…

python之对接有道翻译API接口实现批量翻译

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! python之对接有道翻译API接口实现批量翻译 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&…

使用 C# 进行面向对象编程:第 10 部分

封装和抽象之间的区别 对于 OOP 初学者来说&#xff0c;封装和抽象之间存在非常基本的区别。他们可能会对此感到困惑。但如果你详细了解这两个主题&#xff0c;就会发现它们之间存在巨大差异。 抽象意味着向用户隐藏不必要的数据。用户只需要所需的功能或根据其需求的输出。例…

k8s学习--OpenKruise详细解释以及原地升级及全链路灰度发布方案

文章目录 OpenKruise简介OpenKruise来源OpenKruise是什么&#xff1f;核心组件有什么&#xff1f;有什么特性和优势&#xff1f;适用于什么场景&#xff1f; 什么是OpenKruise的原地升级原地升级的关键特性使用原地升级的组件原地升级的工作原理 应用环境一、OpenKruise部署1.安…

融资融券有哪些交易技巧,两融利率现在最低多少?4.0%!

融资融券交易技巧 授信额度技巧 当我们账户净资产有显著增长时&#xff0c;最好主动申请增加信用额度&#xff0c;这样在后面行情好转入资金需要进行更多融资融券交易时就不会受限于授信额度&#xff0c;避免因为临时申请增加额度而错过交易机会。 买入委托技巧 现金的折算率…

开发一个python工具,pdf转图片,并且截成单个图片,然后修整没用的白边及循环遍历文件夹全量压缩图片

今天推荐一键款本人开发的pdf转单张图片并截取没有用的白边工具 一、开发背景&#xff1a; 业务需要将一个pdf文件展示在前端显示&#xff0c;但是基于各种原因&#xff0c;放弃了h5使用插件展示 原因有多个&#xff0c;文件资源太大加载太慢、pdf展示兼容性问题、pdf展示效…

100V宽电压H62410A恒压芯片 24V降压5V 24V降压12V电源IC

H62410A是一款宽电压100V 内置MOS管的降压恒压芯片&#xff0c;适用于24V降压至5V或12V的应用场景。其内置100V耐压MOS和宽压8V-90V的输入范围&#xff0c;使得它能够在多种电压条件下稳定工作。同时&#xff0c;支持输出电压可调至3.3V&#xff0c;为不同设备提供了灵活的电源…

树莓派4B学习笔记11:PC端网线SSH连接树莓派

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日学习使用网线连接树莓派&#xff0c;网线可以提供更…

Vue46-render函数

一、非单文件和单文件的main.js对比 1-1、非单文件的main.js 1-2、 单文件的main.js 将单文件的main.js中的render函数变成非单文件的main.js中的template形式&#xff0c;报如下错误&#xff1a; 解决方式&#xff1a; 二、解决方式 2-1、引入完成版的vue.js 精简版的vue&a…

TMS320F280049学习5:CPU timer中断

TMS320F280049学习5&#xff1a;CPU timer中断 文章目录 TMS320F280049学习5&#xff1a;CPU timer中断前言一、工程代码二、CPU timer时钟总结 前言 DSP的内部有3个CPU timer&#xff0c;分别是CUP timer0 / 1 / 2&#xff0c;传说CPU timer2一般在跑系统时用&#xff0c;类似…

【Unity】RPG2D龙城纷争(一)搭建项目、导入框架、前期开发准备

更新日期&#xff1a;2024年6月12日。 项目源码&#xff1a;后续章节发布 免责声明&#xff1a;【RPG2D龙城纷争】使用的图片、音频等所有素材均有可能来自互联网&#xff0c;本专栏所有文章仅做学习和教程目的&#xff0c;不会将任何素材用于任何商业用途。 索引 【系列简介】…

DSP教学实验箱_数字图像处理_操作教程:5-1 图像旋转

一、实验目的 学习图像旋转的原理&#xff0c;掌握图像的读取方法&#xff0c;并实现图像旋转。 二、实验原理 图像旋转 图像的旋转是指以图像的某一点为原点以逆时针或顺时针旋转一定的角度。其本质是以图像的中心为原点&#xff0c;将图像上的所有像素都旋转一个相同的角…

PHP邮箱验证码功能优化的策略?怎么配置?

PHP邮箱验证码服务怎么样&#xff1f;如何保障邮箱的安全性&#xff1f; PHP邮箱验证码是验证用户身份的常见方法之一&#xff0c;它通过向用户注册的邮箱发送一次性验证码来确认用户的身份。然而&#xff0c;为了确保这一过程既安全又用户友好&#xff0c;需要一些优化策略来…

hadoop/hive/DBeaver启动流程

hadoop 启动 cd到指定目录下 cd /opt/module/hadoop-3.3.0/sbin/启动文件 ./start-all.shjps一下&#xff0c;查看显示的内容 应该显示以下内容 NameNode SecondaryNameNode DataNode ResourceManager NodeManager如果缺少namenode&#xff0c;那么执行 rm -rf /tmp/hadoo…

flink1.12.0学习笔记(一)-部署与入门

flink1.12.0学习笔记&#xff08;1&#xff09;-部署与入门 1-1-Flink概述 Flink诞生 Flink 诞生于欧洲的一个大数据研究项目 StratoSphere。该项目是柏林工业大学的一个研究性项目。早期&#xff0c; Flink 是做 Batch 计算的&#xff0c;但在 2014 年&#xff0c; StratoS…

Linux_应用篇(19) V4L2 摄像头应用编程

ALPHA/Mini I.MX6U 开发板配套支持多种不同的摄像头&#xff0c;包括正点原子的 ov5640&#xff08;500W 像素&#xff09;、ov2640&#xff08;200W 像素&#xff09;以及 ov7725&#xff08;不带 FIFO、 30W 像素&#xff09;这三款摄像头&#xff0c;在开发板出厂系统上&…

30岁想自学PLC转变职业规划,行业空间如何?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「PLC的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;30岁想自学PLC转变职业规划是…

ollama模型CPU轻量化部署

一、定义 ollama 定义环境部署demo加载本地模型方法基本指令关闭开启ollamaollama 如何同时 运行多个模型, 多进程ollama 如何分配gpu修改模型的存储路径 二、实现 ollama 定义 ollama 是llama-cpp 的进一步封装&#xff0c;更加简单易用&#xff0c;类似于docker. 模型网址…

HTTP协议版本历程

HTTP协议的发展历程 版本推出年份当前状态HTTP/0.91991年已过时HTTP/1.01996年已过时HTTP/1.11997年标准HTTP/2.02015年标准HTTP/3.02022年标准 HTTP/0.9 HTTP/0.9非常简单&#xff0c;并不涉及数据包传输&#xff0c;通过请求和响应的交换达成通信&#xff0c;请求由单行指…