如何用Axios解析Google News跳转链接获取最终文章URL
解决Google News RSS跳转链接提取及OG信息获取问题
问题核心
Google News的RSS跳转链接并非通过HTTP 3xx重定向完成跳转,而是返回一个包含跳转逻辑的HTML页面(比如meta refresh标签或JS跳转),因此Axios的自动重定向机制无法捕捉到最终目标URL,responseUrl始终显示原Google链接。
高效替代方案(无需Puppeteer)
方案1:解码RSS链接的CBM参数(最快)
Google News的/rss/articles/链接中,CBM参数是经过URL安全base64编码的内容,其中直接包含原文章链接。解码该参数即可快速获取目标URL:
import axios from 'axios'; import { Buffer } from 'buffer'; async function extractOriginalUrlFromGoogleRss(googleUrl: string): Promise<string> { try { // 提取CBM参数 const urlParams = new URL(googleUrl).searchParams; const cbmParam = urlParams.get('CBM'); if (!cbmParam) return googleUrl; // 转换为标准base64并解码 const standardBase64 = cbmParam.replace(/-/g, '+').replace(/_/g, '/'); const decodedContent = Buffer.from(standardBase64, 'base64').toString('utf8'); // 匹配原文章链接 const urlMatch = decodedContent.match(/https?:\/\/[^"\s]+/); return urlMatch ? urlMatch[0] : googleUrl; } catch (error) { console.error('解码CBM参数失败:', error); return googleUrl; } }
方案2:解析Google跳转页面HTML(兼容更多场景)
若CBM参数解析失效,可直接请求Google跳转页面,用cheerio解析页面中的跳转目标:
import axios from 'axios'; import cheerio from 'cheerio'; async function getOriginalUrlViaHtmlParse(googleUrl: string): Promise<string> { try { const response = await axios.get(googleUrl, { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } }); const $ = cheerio.load(response.data); // 优先取canonical标签(部分页面直接标注原链接) const canonicalUrl = $('link[rel="canonical"]').attr('href'); if (canonicalUrl) return canonicalUrl; // 解析meta refresh跳转目标 const refreshMeta = $('meta[http-equiv="refresh"]').attr('content'); if (refreshMeta) { const urlMatch = refreshMeta.match(/url=(https?:\/\/[^;]+)/); if (urlMatch) return urlMatch[1]; } return googleUrl; } catch (error) { console.error('解析跳转页面失败:', error); return googleUrl; } }
获取OpenGraph信息
拿到原文章链接后,用axios+cheerio解析页面OG标签:
async function getOpenGraphData(articleUrl: string): Promise<{image?: string; description?: string}> { try { const response = await axios.get(articleUrl, { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } }); const $ = cheerio.load(response.data); return { image: $('meta[property="og:image"]').attr('content'), description: $('meta[property="og:description"]').attr('content') }; } catch (error) { console.error('获取OG信息失败:', error); return {}; } }
使用示例
async function processGoogleNewsItem(googleRssUrl: string) { const originalUrl = await extractOriginalUrlFromGoogleRss(googleRssUrl); const ogData = await getOpenGraphData(originalUrl); console.log('原文章链接:', originalUrl); console.log('OG图片:', ogData.image); console.log('OG描述:', ogData.description); } // 测试调用 processGoogleNewsItem('https://news.google.com/rss/articles/CBMiwAFBVV95cUxNc1hWZ0hlVFNubnVpeWcyMWcwOExOOW0wSlNrRWdTdWtPZlhkZ0dROTdnRnlkNFZ5VnpUSHJyYzlpWkpFeVlORnlWRnFGRmVHLTlYWTN3YmVPUjlrcTRVWGo3Qk9rd1pTX2hkM05xSEtOc1NLNXZFSXVIYjdORjdOT21QUDZyV2VwaHltaVRiQXI3ZkJYSW1PX2RLYWZhWmZ0RFY4cGh5NGFmX3RNRk5sNzlLWW14c3gyNTFGdmkzRkk?oc=5');
内容的提问来源于stack exchange,提问作者Deus
相关产品推荐
相关产品推荐

