使用Axios与JSDOM进行网页爬取无法获取图片src的问题求助
解决Node.js爬取Mangadex图片URL时的DOM元素获取失败问题
我帮你分析下问题所在,以及对应的解决办法:
问题根源
你遇到的核心问题是静态HTML渲染和客户端动态渲染的差异:
- 当你用
axios直接请求https://mangadex.org/titles/latest时,拿到的是网站的初始静态HTML代码,这时候.chapter-feed__container这类元素还不存在——它们是由页面的JavaScript在浏览器中动态生成的。 - 而浏览器控制台里的DOM是经过页面JS执行、渲染完成后的最终DOM,所以能顺利找到目标元素;但
jsdom默认只会解析静态HTML,不会执行页面中的JavaScript,自然找不到你要的元素,进而抛出"无法读取undefined的src属性"这类错误。
解决方案
这里有两种靠谱的解决思路,你可以根据需求选择:
方案1:用Puppeteer模拟真实浏览器渲染
Puppeteer是一个无头浏览器库,能完全模拟浏览器环境,等待页面JS执行完成后再获取DOM元素,和你在浏览器里操作的效果一致。
步骤如下:
- 先安装依赖:
npm install puppeteer
- 替换你的代码为:
const puppeteer = require('puppeteer'); (async () => { // 启动无头浏览器(new模式是最新的无头模式,更高效) const browser = await puppeteer.launch({ headless: 'new' }); const page = await browser.newPage(); // 导航到目标页面,等待网络空闲(确保页面渲染完成) await page.goto('https://mangadex.org/titles/latest', { waitUntil: 'networkidle2' }); // 在页面上下文里执行获取图片src的代码 const imageSrc = await page.evaluate(() => { const imgElement = document.querySelectorAll(".chapter-feed__container a div img")[0]; return imgElement ? imgElement.src : null; }); if (imageSrc) { console.log('获取到的图片URL:', imageSrc); } else { console.log('未找到目标图片元素'); } // 关闭浏览器 await browser.close(); })();
方案2:直接调用Mangadex官方API(更推荐)
爬取页面DOM容易受页面结构变化影响,而调用官方API是更稳定、合规的方式。Mangadex提供了公开的API可以直接获取作品数据,包括封面图片信息。
示例代码(用axios):
const axios = require('axios'); (async () => { try { // 调用API获取最新上传章节的漫画(限制返回1条) const response = await axios.get('https://api.mangadex.org/manga', { params: { limit: 1, order: { latestUploadedChapter: 'desc' } } }); const latestManga = response.data.data[0]; // 从关联数据中找到封面艺术的ID const coverArtRel = latestManga.relationships.find(rel => rel.type === 'cover_art'); if (!coverArtRel) { console.log('未找到封面信息'); return; } // 构造封面图片的URL(文件名直接从接口返回的属性获取) const imageSrc = `https://uploads.mangadex.org/covers/${latestManga.id}/${coverArtRel.attributes.fileName}`; console.log('获取到的封面URL:', imageSrc); } catch (error) { console.error('API请求失败:', error.message); } })();
注意事项
- 无论用哪种方式,都要遵守Mangadex的服务条款和
robots.txt规定,避免频繁请求给服务器造成压力。 - 如果坚持使用
jsdom,可以尝试手动注入页面所需的JavaScript,但这种方式需要分析页面的依赖逻辑,复杂度较高,不推荐。
内容的提问来源于stack exchange,提问作者Gaito Uchiha
相关产品推荐
相关产品推荐

