使用Puppeteer爬取Naver英文字典时返回结果为null的问题求助
嗨,我看你在用Puppeteer爬取Naver英文字典的释义和近义词数据时,遇到了返回结果为null的问题,这就来帮你排查下可能的原因和解决办法~
首先,咱们先从最可能的几个点入手:
一、选择器不准确或元素未加载完成
你代码里用的选择器.section.section_keyword .mean,大概率是没匹配到页面上的元素,所以才返回空。你可以先手动打开目标页面,按F12打开开发者工具,在控制台里输入document.querySelectorAll(".section.section_keyword .mean"),看看能不能拿到对应的释义元素。如果返回空数组,说明这个选择器和页面实际结构不匹配,得调整成正确的选择器。
另外,哪怕你用了waitUntil:'networkidle0',有些动态渲染的元素可能还是没加载好,这时候最好在获取元素前,专门等一下目标元素出现:
// 等待释义元素加载,超时时间设为5秒 await page.waitForSelector(".section.section_keyword .mean", { timeout: 5000 });
这样能确保元素已经渲染到页面上了再去抓取,避免因为元素还没加载导致拿到空结果。
二、代码里的语法小问题
我注意到你代码里的选择器用了"这种转义字符,实际写代码的时候得换成正常的双引号或者单引号,不然会导致语法错误,根本没法正确匹配元素。比如把page.$$(".section.section_keyword .mean");改成page.$$(".section.section_keyword .mean");。
还有你写的近义词部分的选择器.component_summary _thesaurusSwiper .w...,不仅没写完,还有个小错误:_thesaurusSwiper是类名,前面得加个.,应该是.component_summary._thesaurusSwiper,不然也匹配不到对应的容器。
三、可能触发了反爬机制
Naver这类网站可能会检测Puppeteer的默认特征(比如默认的Headless浏览器标识),直接给你返回空内容。你可以模拟正常浏览器的环境来规避:
// 设置正常的User-Agent await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'); // 设置正常的视口大小 await page.setViewport({ width: 1280, height: 800 });
给你整理的修正后示例代码
async function web(word) { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); // 模拟正常浏览器环境 await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'); await page.setViewport({ width: 1280, height: 800 }); const targetUrl = 'https://en.dict.naver.com/#/search?query=' + encodeURIComponent(word); await page.goto(targetUrl, { waitUntil: 'networkidle0' }); console.log(targetUrl); try { // 等待释义元素加载完成 await page.waitForSelector(".section.section_keyword .mean", { timeout: 5000 }); let meandata = await page.$$(".section.section_keyword .mean"); let mean = await page.evaluate(elements => { // 顺便把文本内容的首尾空格去掉,更干净 return elements.map(element => element.textContent.trim()); }, meandata); console.log("释义数据:", mean); // 处理近义词部分(这里用了假设的正确选择器,你可以根据实际页面结构调整) await page.waitForSelector(".component_summary._thesaurusSwiper .word_item", { timeout: 5000 }); let sidata = await page.$$(".component_summary._thesaurusSwiper .word_item"); let similarWords = await page.evaluate(elements => { return elements.map(element => element.textContent.trim()); }, sidata); console.log("近义词数据:", similarWords); } catch (error) { // 加个错误捕获,方便排查哪里出问题 console.error("爬取过程中出错:", error); } finally { // 不管成功失败,最后都关闭浏览器 await browser.close(); } }
最后再提个小建议
每次调整选择器后,都先在浏览器控制台里测试一下,确认能匹配到元素再写到代码里,这样能少走很多弯路~
备注:内容来源于stack exchange,提问作者Account

