使用Axios+Cheerio抓取谷歌汇率时,无法获取span的data-value属性
问题排查&修复方案
嘿,我帮你捋捋这个问题——你打印选择器结果的时候,里面有个关键细节:length: 0,这说明cheerio完全没匹配到span.DFlfde.SwHCTb这个元素,主要原因有两个:
1. 页面是动态渲染的
Google搜索的汇率模块是靠JavaScript动态生成的,axios发请求拿到的只是初始的静态HTML源码,根本没执行页面里的JS,所以你要的那个span标签还没被渲染出来,自然找不到。
2. 反爬机制在搞事情
Google会检查请求的User-Agent,axios默认的UA是axios/x.x.x这种,一看就是爬虫,可能直接返回不完整的内容,或者篡改了页面结构,导致你拿不到目标元素。
修复方案一:用Puppeteer模拟浏览器(最靠谱的办法)
Puppeteer能模拟真实浏览器加载页面,等JS执行完、元素渲染出来再去抓取,完美解决动态内容的问题。给你写个示例代码:
const puppeteer = require('puppeteer'); (async () => { // 启动浏览器,headless: true表示无头模式,想调试可以改成false const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); // 设置真实的User-Agent,假装是Chrome浏览器请求 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'); const url = 'https://www.google.com/search?q=sgd+myr&spell=1&sa=X&ved=2ahUKEwiStvfn5ozoAhVWH7cAHQJZCpwQBSgAegQIDRAm&biw=960&bih=746'; await page.goto(url); // 等目标元素加载出来再操作,避免提前抓取导致空结果 await page.waitForSelector('span.DFlfde.SwHCTb'); // 获取元素的data-value属性 const exchangeRate = await page.$eval('span.DFlfde.SwHCTb', el => el.getAttribute('data-value')); console.log('汇率数据:', exchangeRate); await browser.close(); })();
修复方案二:给axios加请求头(不一定能搞定Google,但可以试试)
如果不想用Puppeteer,你可以给axios加更真实的请求头,假装是用户在浏览器里访问:
const axios = require('axios'); const cheerio = require('cheerio'); const url = 'https://www.google.com/search?q=sgd+myr&spell=1&sa=X&ved=2ahUKEwiStvfn5ozoAhVWH7cAHQJZCpwQBSgAegQIDRAm&biw=960&bih=746'; axios(url, { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'Accept-Language': 'en-US,en;q=0.9' // 加上语言头,更贴合真实请求 } }) .then(response => { const html = response.data; const $ = cheerio.load(html); const targetSpan = $('span.DFlfde.SwHCTb'); if (targetSpan.length > 0) { console.log('拿到的数据:', targetSpan.attr('data-value')); } else { console.log('还是没找到元素,大概率是页面动态渲染的问题,建议用Puppeteer'); } }) .catch(err => console.error('请求出错:', err));
小提醒
- Google的页面结构和反爬规则经常变,要是以后这个选择器失效了,记得去浏览器里重新检查元素的最新class和结构。
- 别频繁刷请求,不然容易被Google封IP,最好加个请求间隔,比如每次抓取后等个几秒。
内容的提问来源于stack exchange,提问作者Tommy Leong
相关产品推荐
相关产品推荐

