如何使用Cheerio与jsdom解析复杂的HTML结构进行数据提取

news2024/9/22 19:24:28

亿牛云代理.png

背景介绍

在现代网页开发中,HTML结构往往非常复杂,包含大量嵌套的标签和动态内容。这给爬虫技术带来了不小的挑战,尤其是在需要精确提取特定数据的场景下。传统的解析库可能无法有效处理这些复杂的结构,而JavaScript环境下的Cheerio和jsdom提供了强大的工具,帮助开发者在Node.js环境中高效解析和处理HTML文档。

问题陈述

如何在复杂的HTML结构中精确地提取数据,成为了许多爬虫开发者面临的核心问题。特别是在面对需要代理IP、cookie和user-agent设置以及高效多线程处理的需求时,如何将这些技术合理整合在一起,以确保数据的准确性和采集的高效性,是本文要探讨的重点。

解决方案

使用Cheerio和jsdom可以在Node.js环境中高效解析和操作HTML文档。这两个库各有特点:Cheerio提供了类似jQuery的API,方便处理DOM,而jsdom则更接近真实的浏览器环境,适合处理需要执行JavaScript的动态内容。结合代理IP、cookie、user-agent设置,以及多线程技术,可以显著提高数据采集的效率和可靠性。

案例分析

下面我们将通过一个具体的示例来演示如何使用Cheerio和jsdom解析复杂的HTML结构,并结合代理IP、cookie和user-agent的设置,实现高效的数据提取和归类统计。

示例代码
const axios = require('axios');
const cheerio = require('cheerio');
const { JSDOM } = require('jsdom');
const HttpsProxyAgent = require('https-proxy-agent');
const { spawn } = require('child_process');
const os = require('os');

// 代理配置 - 使用亿牛云爬虫代理服务 www.16yun.cn
const proxy = {
    host: 'proxy.16yun.cn', // 代理域名
    port: 8000, // 代理端口
    auth: {
        username: 'your_username', // 代理用户名
        password: 'your_password'  // 代理密码
    }
};

// 创建代理Agent
const proxyAgent = new HttpsProxyAgent(`http://${proxy.auth.username}:${proxy.auth.password}@${proxy.host}:${proxy.port}`);

// 设置cookie和user-agent
const headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
    'Cookie': 'your_cookie_here'
};

// 待解析的URL
const url = 'http://www.soufun.com.cn';

// 多线程处理函数
function fetchData() {
    return new Promise((resolve, reject) => {
        axios.get(url, { headers, httpsAgent: proxyAgent })
            .then(response => {
                const dom = new JSDOM(response.data);
                const $ = cheerio.load(dom.window.document);

                // 使用Cheerio选择器提取数据
                const propertyList = [];
                $('div.property-item').each((i, el) => {
                    const property = {
                        title: $(el).find('h2').text().trim(),
                        price: $(el).find('.price').text().trim(),
                        location: $(el).find('.location').text().trim(),
                        type: $(el).find('.type').text().trim()
                    };
                    propertyList.push(property);
                });

                resolve(propertyList);
            })
            .catch(error => reject(error));
    });
}

// 创建多线程
function createWorkers(workerCount) {
    const workers = [];
    for (let i = 0; i < workerCount; i++) {
        const worker = spawn(os.platform() === 'win32' ? 'cmd' : 'sh', [], {
            stdio: 'inherit'
        });

        worker.on('message', fetchData);

        workers.push(worker);
    }
    return workers;
}

// 启动多线程采集并进行数据归类和统计
async function startScraping(workerCount) {
    const workers = createWorkers(workerCount);

    const results = await Promise.all(workers.map(worker => fetchData()));

    // 归类和统计数据
    const categorizedData = {};
    results.flat().forEach(property => {
        const type = property.type;
        if (!categorizedData[type]) {
            categorizedData[type] = [];
        }
        categorizedData[type].push(property);
    });

    // 打印统计结果
    for (const type in categorizedData) {
        console.log(`房产类型: ${type}`);
        console.log(`数量: ${categorizedData[type].length}`);
        console.log('详细信息:', categorizedData[type]);
        console.log('---');
    }
}

// 调用多线程爬虫
startScraping(4); // 启动4个线程
代码解析
  1. 目标网站更改:将url变量更改为http://www.soufun.com.cn,这使得爬虫针对新的目标网站进行数据采集。
  2. 数据提取:在fetchData函数中,使用Cheerio选择器提取房产信息,包括title(房产标题)、price(价格)、location(地点)和type(房产类型)。这些信息被存储在propertyList数组中。
  3. 数据归类和统计
    • 将提取到的房产信息按type(房产类型)进行归类,每个房产类型对应一个数组,数组中包含所有该类型的房产信息。
    • 统计每种房产类型的数量,并输出详细的统计结果。
  4. 多线程处理:保持了原有的多线程架构,通过并发请求提高数据采集效率。
结论

本文介绍了如何结合Cheerio和jsdom解析复杂的HTML结构,并通过代理IP、cookie、user-agent的设置,以及多线程技术,提升数据采集的效率和准确性。通过对http://www.soufun.com.cn网站的具体示例,展示了如何将采集到的数据进行有效的归类和统计。这种组合方式适用于复杂的网页解析场景,可以帮助开发者在面对高难度任务时,轻松实现高效的数据提取。
这种方法特别适用于需要处理大量分类数据的爬虫任务,有助于更快地获取并分析所需信息。如果你在爬虫开发过程中遇到类似的难题,不妨尝试本文介绍的方法,或许会有意想不到的收获!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习(五) -- 监督学习(8) --神经网络2

机器学习系列文章目录及序言深度学习系列文章目录及序言 上篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;8&#xff09; --神经网络1 下篇&#xff1a; 前言 tips&#xff1a;标题前有“***”的内容为补充内容&#xff0c;是给好奇心重的宝宝看…

Fast Vision Transformers with HiLo Attention

总结 提出了 HiLo Attention 机制&#xff1a; 该机制将自注意力层分为两部分&#xff1a;Hi-Fi&#xff08;高频注意力&#xff09; 和 Lo-Fi&#xff08;低频注意力&#xff09;。Hi-Fi 捕捉局部细节&#xff0c;通过在局部窗口内应用自注意力&#xff0c;减少了计算复杂度…

图文解析保姆级教程:Tomcat下载、安装、卸载、启动、关闭,解决窗口闪退问题、端口号冲突问题

文章目录 1. 下载2. 安装与卸载3. 启动与关闭4. 常见问题问题1&#xff1a;Tomcat启动时&#xff0c;窗口一闪而过问题2&#xff1a;端口号冲突&#xff08;Tomcat使用的端口被占用&#xff09; 此教程摘选自我的笔记&#xff1a;黑马JavaWeb开发笔记14——Tomcat&#xff08;介…

linux进程处理

1.测试这样没意义&#xff0c;要向后加 wait等待进程结束 1. 2.测试 发送异常结束的信号&#xff0c;通过kill 二、子进程的回收 对于子进程的结束而言&#xff0c;都希望父进程能够知道并作出一定的反应&#xff0c;通过 wait、waitpid 函数可以知道子进程是如何结束的…

人工智能训练师边缘计算实训室解决方案

一、引言 随着物联网&#xff08;IoT&#xff09;、大数据、人工智能&#xff08;AI&#xff09;等技术的飞速发展&#xff0c;计算需求日益复杂和多样化。传统的云计算模式虽在一定程度上满足了这些需求&#xff0c;但在处理海量数据、保障实时性与安全性、提升计算效率等方面…

使用VM创建centos7环境

1、安装VMware Workstation 1.1安装VMware Workstation pro 16 修改自己的安装位置 一直下一步到 1.2激活VMware Workstation pro 16 点击许可证 解压这个压缩包&#xff0c;密码是ai95 之后找到下面文件打开 将生成的许可证码输入到安装VMware Workstation pro 16完成安…

gitk无法打开

1、电脑重装&#xff0c;重新安装git工具后&#xff0c;发现无法打开现有的仓库&#xff0c;报错如下&#xff1a; 搜索网上的信息&#xff0c;显示是目录下没有.git文件夹&#xff0c;但是在xshell查看文件夹是存在的。 然后进行测试git log指令发现也无法进行显示。 然后按…

OJ习题 篇2

&#x1f680;个人主页&#xff1a;奋斗的小羊 &#x1f680;所属专栏&#xff1a;C 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 &#x1f4a5;1、删除有序数组中的重复项&#x1f4a5;2、数组中出现次数超过一半的数字&#x1f4a5;3、最…

python 怎么样反向输出字符串

python如何反向输出字符串&#xff1f;下面给大家介绍两种方法&#xff1a; 方法一&#xff1a;采用列表reversed函数 class Solution(object):def reverse_string(self, s):if len(s) > 1:reversed_s .join(reversed(s))return reversed_s return s 方法二&#xff1a;采…

爬取图片保存为pdf

本文章想借着爬虫给大家介绍一下图片转pdf,有需要的友友们可以看看参考参考&#xff0c;有帮助到友友的可以收藏&#xff0b;关注。下面以爬取初中7年级数学上册为例给大家演示一下。网址是这个 https://mp.weixin.qq.com/s?__bizMzAxOTE4NjI1Mw&mid2650214000&idx…

10-1 注意力提示

感谢读者对本书的关注&#xff0c;因为读者的注意力是一种稀缺的资源&#xff1a; 此刻读者正在阅读本书&#xff08;而忽略了其他的书&#xff09;&#xff0c; 因此读者的注意力是用机会成本&#xff08;与金钱类似&#xff09;来支付的。 为了确保读者现在投入的注意力是值得…

巨魔商店2.1正式更新,最高支持iOS17.6.1

巨魔商店2.1&#xff0c;来了 不得不说&#xff0c;我此刻的心情&#xff0c;确实有点振奋。一天之内&#xff0c;巨魔连续传来2个大动作。 一个是iOS17.0有了刷巨魔的正式方法&#xff0c;iPhone 15点燃了巨魔的火种。 另一个就是巨魔商店的开发者opa334&#xff0c;突然发…

Postgresql碎片整理

创建pgstattuple 扩展 CREATE EXTENSION pgstattuple 获取表的元组&#xff08;行&#xff09;信息&#xff0c;包括空闲空间的比例和行的平均宽度 SELECT * FROM pgstattuple(表名); 查看表和索引大小 SELECT pg_relation_size(表名), pg_relation_size(索引名称); 清理碎片方…

【鸿蒙HarmonyOS NEXT】List组件的使用

【鸿蒙HarmonyOS NEXT】List组件的使用 一、环境说明二、List组件及其使用三、示例代码如下 一、环境说明 DevEco Studio 版本&#xff1a;DevEco Studio NEXT Developer Beta5 Build #DS-233.14475.28.36.503700 Build Version: 5.0.3.700, built on August 19, 2024 Runtime…

实战docker第二天——cuda11.8,pytorch基础环境docker打包

在容器化环境中打包CUDA和PyTorch基础环境&#xff0c;可以将所有相关的软件依赖和配置封装在一个Docker镜像中。这种方法确保了在不同环境中运行应用程序时的一致性和可移植性&#xff1a; Docker&#xff1a;提供了容器化技术&#xff0c;通过将应用程序及其所有依赖打包在一…

★ 算法OJ题 ★ 力扣209 - 长度最小的子数组

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;简将和大家一起做一道滑动窗口算法题--长度最小的子数组~ 目录 一 题目 二 算法解析 解法⼀&#xff1a;暴力求解 解法二&#xff1a;滑动窗口 三 编写算法 一 题目 209. 长度最小的子数组 - 力扣&#xff08…

Python Mail:如何设置SMTP服务器发邮件?

Python Mail发送邮件的步骤&#xff1f;如何使用Python 发邮件&#xff1f; 在现代通信中&#xff0c;电子邮件仍然是不可或缺的一部分。Python Mail 提供了一种简单而强大的方式来通过 SMTP 服务器发送邮件。AokSend将详细介绍如何使用 Python Mail 库来设置和发送电子邮件。…

echart自适应tree树图,结构组织图模板

处理数据(代码中有处理数据逻辑&#xff0c;可忽略&#xff0c;因为后端返回的格式不匹配&#xff0c;需要自己处理) [{ name: ‘test1’, children: [{ name: ‘test2’ }] }] <template><div class"boxEchart"><div ref"echart" :style&…

9.3javaweb总结

1.axios交互 发送数据到后端。 alert(注册成功&#xff08;数据正在发送后端&#xff09;!);// 获取表单数据//const formData new URLSearchParams(new FormData(document.getElementById("register-form"))).toString();const form document.getElementById(&q…

深度学习——基于MTCNN算法实现人脸侦测

这里写目录标题 先看效果 MTCNN主体思想级联网络图像金字塔IOU算法iou 公式 nms 算法数据生成celeba 数据代码训练代码侦测代码总结 先看效果 MTCNN 从2016年&#xff0c;MTCNN算法出来之后&#xff0c;属实在工业上火了一把&#xff0c;最近尝试着把论文代码复现了一下。 主…