新闻中心

使用 JSDOM 抓取网页时 NodeList 长度为 0 的问题及解决方案

2025-11-16
浏览次数:
返回列表

使用 jsdom 抓取网页时 nodelist 长度为 0 的问题及解决方案

在使用 JSDOM 和 Axios 进行网页抓取时,有时会遇到使用 querySelectorAll 查询

  • 元素时返回的 NodeList 长度为 0 的问题,即使页面上明明存在这些元素。这通常是由于目标网站的特殊机制,例如首次请求时服务器不返回完整的内容,或者依赖于 cookies 或缓存等。本教程将深入探讨这个问题,并提供一种使用 Puppeteer 解决该问题的方案,确保能够正确抓取到目标元素。

    问题分析

    当使用 JSDOM 和 Axios 抓取网页时,你可能会遇到以下情况:

    1. 通过 querySelector 成功获取到
        元素。
    2. ulist.childElementCount 返回 1,表示
        元素下只有一个子元素。
    3. 使用 querySelectorAll('li') 查询
    4. 元素时,返回的 NodeList 长度为 0。

    这种现象表明,目标网站可能存在一些特殊的机制,导致 JSDOM 在首次请求时无法获取到完整的 DOM 结构。可能的原因包括:

    • 服务器端动态渲染: 网站可能使用 J*aScript 在客户端动态生成
    • 元素,而 JSDOM 在首次请求时可能无法执行这些 J*aScript 代码。
    • Cookies 或缓存依赖: 网站可能依赖于 cookies 或缓存来确定是否返回完整的 HTML 内容。首次请求时,由于缺少 cookies 或缓存,服务器可能只返回部分 HTML。
    • 反爬虫机制: 网站可能存在一些简单的反爬虫机制,例如根据 User-Agent 判断请求是否来自爬虫,并返回不同的内容。

    解决方案:使用 Puppeteer

    Puppeteer 是一个 Node.js 库,它提供了一个高级 API 来控制 Chrome 或 Chromium。与 JSDOM 不同,Puppeteer 可以执行 J*aScript 代码,并模拟用户的完整浏览行为,包括处理 cookies、缓存和执行 J*aScript 渲染。

    Visla Visla

    AI视频生成器,快速轻松地将您的想法转化为视觉上令人惊叹的视频。

    Visla 100 查看详情 Visla

    以下是使用 Puppeteer 解决该问题的示例代码:

    const puppeteer = require('puppeteer');
    
    (async () => {
      const browser = await puppeteer.launch({ headless: true }); // 启动无头浏览器
      const page = await browser.newPage(); // 创建新的页面
    
      // 访问首页,解决可能的缓存或 Cookie 问题
      await page.goto('http://example.com'); 
    
      // 访问目标页面
      await page.goto('https://example.com/targetpage');
    
      // 等待 #download-options li 元素加载完成,确保页面渲染完成
      await page.waitForSelector('#download-options li');
    
      // 获取 ul 元素
      const ul = await page.$("#download-options ul");
    
      // 获取所有的 li 元素
      const lis = await ul.$$("li");
    
      // 循环遍历 li 元素,获取 href 属性值
      for await (const li of lis) {
        const a = await li.$('a');
        const hrefValue = await a.evaluate((el) => el.getAttribute('href'));
        console.log(hrefValue);
      }
    
      // 关闭浏览器
      await browser.close();
    })();

    代码解释:

    1. puppeteer.launch({ headless: true }): 启动一个无头浏览器,headless: true 表示在后台运行,不显示浏览器界面。
    2. page.goto('http://example.com'): 首先访问网站的首页。这步很重要,因为有些网站的行为会依赖于是否已经访问过首页,例如设置 cookies 或者初始化某些状态。
    3. page.goto('https://example.com/targetpage'): 访问目标页面。
    4. page.waitForSelector('#download-options li'): 等待 #download-options li 元素加载完成。这可以确保页面上的 J*aScript 代码已经执行完毕,并且
    5. 元素已经渲染到 DOM 中。
    6. page.$("#download-options ul"): 使用 CSS 选择器获取
        元素。
    7. ul.$$("li"): 在
        元素下使用 CSS 选择器获取所有的
      • 元素。 $$ 相当于 querySelectorAll。
      • a.evaluate((el) => el.getAttribute('href')): 使用 evaluate 方法在浏览器环境中执行 J*aScript 代码,获取 元素的 href 属性值。

    注意事项:

    • 确保已安装 Puppeteer: npm install puppeteer
    • headless: true 可以在后台运行浏览器,如果需要查看浏览器界面,可以将其设置为 false。
    • page.waitForSelector 用于等待元素加载完成,可以根据实际情况调整选择器和等待时间。
    • Puppeteer 消耗资源较多,建议在使用完毕后关闭浏览器。

    总结

    当使用 JSDOM 无法正确抓取网页内容时,可以考虑使用 Puppeteer。Puppeteer 可以模拟用户的完整浏览行为,执行 J*aScript 代码,并处理 cookies 和缓存,从而解决 JSDOM 无法获取完整 DOM 结构的问题。通过访问首页并等待元素加载完成,可以确保 Puppeteer 能够正确抓取到目标元素。

  • 以上就是使用 JSDOM 抓取网页时 NodeList 长度为 0 的问题及解决方案的详细内容,更多请关注其它相关文章!


    # 网页时  # 国内营销型网站建设价格  # 广告网站建设方案咨询  # 江西网站优化公司  # 赣州网站建设必备知识  # 营销推广主题文案  # 女装行业品牌推广营销  # 推广app赚钱的网站  # 中山大型网站推广  # 焦作网站推广外包  # seo助手哪个便宜些啊  # 关闭浏览器  # 依赖于  # 视频文件  # 如何使用  # 加载  # css  # 选择器  # 长度为  # 首页  # 首次  # a  # 浏览器  # npm  # cookie  # go  # node  # node.js  # js  # html  # java  # javascript 


    相关栏目: 【 科技资讯46185 】 【 网络学院92790


    相关推荐: Golang如何通过reflect操作map_Golang reflect map操作与遍历技巧  J*aScript实现单选按钮与关联输入框的联动禁用教程  虚幻5科幻题材ARPG大作遭取消!本是《奇异人生》厂商新作  优酷会员付费后没到账怎么办_优酷会员充值异常及解决方法  Lar*el头像管理:图片缩放与旧文件删除的最佳实践  必由学官方平台入口 必由学在线课堂登录地址  J*a递归快速排序中静态变量的状态管理与陷阱  LINUX的I/O重定向是什么_深入理解LINUX中 >、>> 与 < 的区别  2025AO3夸克浏览器通道_AO3手机HTTPS安全入口分享  126邮箱账号注册 电脑版登录入口  构建轻量级网站内部消息系统:Formspree 集成指南  如何在低配置电脑上搭建轻量级J*a环境_占用更小的环境选择技巧  在J*a中如何使用BigDecimal进行高精度计算_BigDecimal类应用指南  在J*a中如何隐藏复杂性_使用门面模式组织对象交互  Steam官网入口直达 Steam注册及登录步骤  荒野行动PC版怎么注册_荒野行动PC版账号注册详细流程图文教程  vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧  如何使用Rector自动化升级旧代码_通过Composer安装和配置Rector进行代码重构  J*aScript map 方法中处理循环元素为空数组的策略  HTML长属性值处理:表单action路径优化与代码规范应对  php源码怎么在电脑上测试_电脑测试php源码方法步骤【教程】  Composer的 "check-platform-reqs" 命令有什么用_在部署前检查生产环境是否满足Composer依赖需求  Excel函数批量查找替换超快方法_Excel用REPLACE和FIND函数秒级替换  QQ邮箱官方网页版登录 QQ邮箱个人邮箱快速访问  MongoDB聚合管道:正确匹配对象数组中_id的方法  VS Code远程开发时如何处理文件权限问题  C#如何安全地从用户上传的XML文件中读取数据? 验证与清理策略  4399免费游戏网址入口 4399小游戏免费入口点开即玩  痛风发作了怎么办? 快速止痛和后期饮食调理  C++如何实现一个智能指针_手动实现C++ shared_ptr的引用计数功能  解决 Vaadin 8 中大文件音频播放与定位时出现的 IOException  excel如何生成目录 excel一键生成工作表目录超链接  mysql通配符支持数字匹配吗_mysql通配符能否用于数字匹配的解析  怎么在html里运行vbs脚本_html中运行vbs脚本方法【教程】  文心一言怎样用插件调度API数据_文心一言用插件调度API数据【API调用】  C++指针和引用有什么区别_C++内存管理核心概念深度解析  C++如何操作注册表_Windows平台下C++读写注册表的API函数详解  小红书商家版怎样在笔记嵌入商品卡路径_小红书商家版在笔记嵌入商品卡路径【挂载教程】  Win11截图该按哪些键 Win11截屏完整流程解析【教程】  QQ邮箱稳定登录入口_QQ邮箱官方网站网页版使用  QQ邮箱在线使用入口 QQ邮箱个人账号网页版登录  c++中的std::launder有什么实际用途_c++对象生命周期与指针优化  KFC早餐时段怎么领特惠代码_KFC早餐订餐优惠代码获取与使用说明  微信商城在哪里打开【步骤】  随机参数递归函数的基准调用次数与时间复杂度探究  Win10文件资源管理器“此电脑”分组怎么关 Win10恢复经典视图【技巧】  PowerPoint如何制作滚动字幕结尾彩蛋_PowerPoint路径动画实现平滑滚动字幕效果  如何有效阻止外部脚本意外修改内联样式的高度属性  UC浏览器如何安装插件 UC浏览器添加扩展程序详细教程【进阶】  极速漫画官方主页网址 极速漫画漫画在线浏览官网链接 

    搜索