Google News 将来自数千家出版商的头条新闻汇聚成一个持续刷新的信息流,对于追踪某个话题、观察一则新闻的传播方式,或构建"谁在何时报道了什么"数据集的人来说,这是一个极具吸引力的来源。问题在于,该页面是为浏览器而非脚本设计的:它在客户端渲染,并对自动化流量发起挑战,因此普通 HTTP 请求只会返回一个近乎空白的框架,而非你所需要的头条新闻。

本指南将向你展示如何使用 JavaScript 抓取 Google News。你将构建一个小而可运行的 Node 脚本,通过 Crawlbase Smart AI Proxy获取已渲染的页面,然后使用 Cheerio 解析标题、发布方、发布时间和作者,并将结果写出为 JSON。本指南的所有内容都限定在无需登录即可看到的公开结果范围内,文末的合法性章节值得在指向任何真实流量之前仔细阅读。

为什么要抓取 Google News

访问一次 Google News 只能告诉你某一时刻信息流的状态。抓取它的价值在于将这个动态流转化为可以存储、查询和随时间比较的结构化行。几个具体的使用场景:

  • 趋势和话题追踪。 观察哪些报道在一次查询中浮现,以及覆盖度如何在一天内变化,这对研究、新闻工作和 SEO 规划都很有价值。
  • 竞品和品牌监控。 在一次遍历中收集跨多家媒体的公司、产品或高管的相关报道,无需逐站手动查阅。
  • 市场和金融信号。 汇聚某个行业或股票代码的相关头条,用于驱动仪表盘或模型。
  • 内容策划。 将新鲜的相关头条拉入通讯或内部信息流,无需手动搜罗各个来源。

每种场景的输出形态相同:标题、来源、时间戳、链接和作者等行,可用于有意义的后续处理。这正是本爬虫所生成的数据。

可以提取哪些数据

在编写选择器之前,了解 Google News 结果页面上存在哪些字段以及值得提取哪些字段会很有帮助。信息流中每篇文章卡片都暴露了一组可预测的值:

  • 标题。 文章在信息流中显示的标题。
  • 发布方。 发布该报道的媒体来源(CNN、The Hill 等)。
  • 发布时间。 相对时间戳,如"21分钟前"或"9小时前"。
  • 作者。 当卡片显示署名时的作者信息;很多卡片没有,预期会有空值。
  • 文章链接。 标题上的 href,指向原始出版商的页面。

这组字段覆盖了大多数监控和研究任务。下面的代码中我们将提取标题、发布方、时间和作者;一旦你拿到了卡片,提取链接只需一行代码。

为什么普通请求会失败

用普通 HTTP 客户端请求 Google News URL,你会得到一个 200 响应,但响应体大多是一个空框架。有两个因素对你不利。第一,信息流在浏览器中渲染:初始 HTML 是一个薄壳,只有页面 JavaScript 运行后才会填充。第二,Google 能迅速识别自动化流量,数据中心 IP 和非浏览器请求模式会在到达已渲染内容之前被限速或发起挑战。

因此,一个可用的 Google News 爬虫需要同时满足两点:像真实浏览器一样渲染页面的工具,以及平台视为真实访客的 IP。你可以自行用无头浏览器加轮换 IP 地址池来搭建,但组建并维护这套系统是大部分的工作量。Crawlbase Smart AI Proxy 将两者融合进一个端点:将你的普通 HTTP 客户端指向它,它就会通过轮换的住宅和数据中心 IP 路由请求,并将页面返回给你解析。

Smart AI Proxy 还是 Crawling API

Smart AI Proxy 是一个直接替换的代理端点:你保持使用现有的 HTTP 客户端,只改变连接的目标。它在内部转发到 Crawling API,因此你可以获得相同的渲染和 IP 轮换能力。如果你希望直接调用 API 并显式传入 JavaScript 渲染等选项,则使用 Crawling API;本指南采用代理路由,因为它对普通请求改动最小。

前提条件

在编写任何代码之前,你需要三样东西:

  • 已安装 Node.js。 Node 可以在浏览器之外运行 JavaScript,并提供 npm 用于安装库。用 node --version 确认。
  • 基础 JavaScript 知识。 熟悉变量、函数和异步调用即可跟上本指南。
  • Crawlbase token。 注册一个免费账户,打开 Smart AI Proxy 控制台,从连接详情中复制访问 token。该 token 作为你的代理用户名,直接包含在请求中。

设置项目

创建项目文件夹,初始化项目,并安装爬虫所需的两个库。

bash
node --version

mkdir google-news-scraper && cd google-news-scraper
npm init -y
npm install axios cheerio

两个依赖项各司其职:axios 发起 HTTP 请求,且易于配置代理;cheerio 用类 jQuery 的 API 在服务端解析返回的 HTML。Node 内置的 httpsfs 模块负责代理代理和文件写入,无需额外安装。

通过 Smart AI Proxy 获取已渲染的页面

首要任务是获取已完成的 HTML。你配置一个指向 Smart AI Proxy 主机和端口的 HTTPS 代理,将 token 作为代理用户名传入,让 axios 通过它发送请求。代理渲染页面并返回真实标记,而非直接请求时得到的空壳。将 YOUR_CRAWLBASE_TOKEN 替换为你控制台中的 token。

javascript
const axios = require('axios')
const https = require('https')
const fs = require('fs')

const token = 'YOUR_CRAWLBASE_TOKEN'
const url = 'https://news.google.com/home?hl=en-US&gl=US&ceid=US%3Aen'

const agent = new https.Agent({
  proxy: {
    host: 'smartproxy.crawlbase.com',
    port: 8012,
    auth: { username: token },
  },
  rejectUnauthorized: false,
})

async function fetchGoogleNews(target) {
  const response = await axios.get(target, { httpsAgent: agent })
  fs.writeFileSync('response.html', response.data)
  console.log('Status:', response.status, '- saved response.html')
  return response.data
}

fetchGoogleNews(url).catch((err) => console.error('Fetch failed:', err.message))

这里有几个细节在发挥作用。代理将每个请求路由到 smartproxy.crawlbase.com8012 端口,你的 token 作为代理用户名随请求传入,rejectUnauthorized: false 允许代理终止 TLS 而不产生证书不匹配的错误。将响应体保存到 response.html,意味着你可以只获取一次,然后在本地文件上反复迭代选择器,而不必为每次修改都消耗一次请求。

node scraper.js 运行它。你应当看到 200 状态码,以及一个包含真实文章标记的 response.html,而非空框架。这可以在编写任何选择器之前确认渲染和路由是否正常工作。

Crawlbase Smart AI Proxy

Google News 需要在可信 IP 后方渲染页面,Smart AI Proxy 同时提供了这两点,无需改变你的代码发起请求的方式。将你现有的 HTTP 客户端指向代理端点,它就会轮换住宅和数据中心 IP,渲染页面,并返回已完成的 HTML,省去了自行运营无头浏览器集群和代理池的麻烦。先用免费额度对公开信息流进行测试。

用 Cheerio 解析结果

有了保存的 HTML,将其加载到 Cheerio 中并遍历文章卡片。每个卡片都包含你需要的字段,任务是在卡片内将标题、发布方、时间和作者映射到正确的选择器。在浏览器开发者工具中检查实时结果页面以确认当前的 class 名称,然后进行配置。

javascript
const fs = require('fs')
const cheerio = require('cheerio')

function parseArticle(card) {
  return {
    headline: card.find('a.gPFEn').text().trim(),
    publisher: card.find('.vr1PYe').text().trim(),
    time: card.find('time.hvbAAd').text().trim(),
    author: card.find('.bInasb span[aria-hidden="true"]').text().trim(),
  }
}

function extractArticles(html) {
  const $ = cheerio.load(html)
  const articles = []

  $('article.UwIKyb').each((i, el) => {
    articles.push(parseArticle($(el)))
  })

  return articles
}

逻辑很直观:选取每个 article 卡片,然后对每个卡片提取标题链接、发布方标签、<time> 元素和作者 span。每次调用上的 .trim() 去除 Google 标记留下的多余空白。要同时捕获链接,在 parseArticle 内用 card.find('a.gPFEn').attr('href') 读取标题的 href 即可。

选择器会漂移

Google 的 class 名称(如 gPFEnUwIKyb 这样的短哈希字符串)会在没有通知的情况下发生变化。将上面的选择器视为起始模板,而非合同。当某个字段开始返回空字符串时,在浏览器开发者工具中重新检查实时页面并更新选择器。这是任何生产爬虫的例行维护工作,并不意味着出了什么问题。

完整爬虫代码

以下是获取和解析串接成一个可运行文件的完整代码。它通过 Smart AI Proxy 请求页面,保存 HTML,解析卡片,并打印结构化结果。放入你的 token 后直接运行。

javascript
const axios = require('axios')
const https = require('https')
const fs = require('fs')
const cheerio = require('cheerio')

const token = 'YOUR_CRAWLBASE_TOKEN'
const url = 'https://news.google.com/home?hl=en-US&gl=US&ceid=US%3Aen'

const agent = new https.Agent({
  proxy: {
    host: 'smartproxy.crawlbase.com',
    port: 8012,
    auth: { username: token },
  },
  rejectUnauthorized: false,
})

async function fetchGoogleNews(target) {
  const response = await axios.get(target, { httpsAgent: agent })
  fs.writeFileSync('response.html', response.data)
  return response.data
}

function parseArticle(card) {
  return {
    headline: card.find('a.gPFEn').text().trim(),
    publisher: card.find('.vr1PYe').text().trim(),
    time: card.find('time.hvbAAd').text().trim(),
    author: card.find('.bInasb span[aria-hidden="true"]').text().trim(),
  }
}

function extractArticles(html) {
  const $ = cheerio.load(html)
  const articles = []
  $('article.UwIKyb').each((i, el) => articles.push(parseArticle($(el))))
  return articles
}

async function main() {
  const html = await fetchGoogleNews(url)
  const articles = extractArticles(html)
  fs.writeFileSync('articles.json', JSON.stringify(articles, null, 2))
  console.log(articles)
}

main().catch((err) => console.error('Scrape failed:', err.message))

输出结果示例

运行完整脚本,你将获得一个结构化文章对象的数组,写入 articles.json 并回显到控制台。一个精简示例:

json
[
  {
    "headline": "Morning Report: Biden, Trump duel over border during separate Texas stops",
    "publisher": "The Hill",
    "time": "21 minutes ago",
    "author": "Alexis Simendinger & Kristina Karisch"
  },
  {
    "headline": "Takeaways from the dueling border visits",
    "publisher": "CNN",
    "time": "9 hours ago",
    "author": ""
  },
  {
    "headline": "Funeral draws crowds to Moscow church despite tight security",
    "publisher": "CBS News",
    "time": "5 minutes ago",
    "author": "Haley Ott"
  }
]

注意第二个卡片的作者为空。许多 Google News 条目不带署名,所以空值是正常的,而不是解析错误。根据你的任务需要,在下游过滤或设置这些字段的默认值。

保持不被封锁

即使渲染和轮换已处理好,Google 仍会监控爬虫形态的流量。以下几个习惯有助于保持运行健康,适用于任何高强度目标。

  • 控制请求节奏。 在紧密循环中大量请求同一信息流是触发限速的最快方式。分散请求,变换查询或话题。
  • 依赖轮换。 将请求分散到众多真实用户 IP 上,避免单个地址触发速率限制。Smart AI Proxy 会替你处理这个问题;如果你自行搭建,权衡数据中心代理与住宅代理的优劣,并做好轮换。
  • 关注状态码。 运行开始返回挑战或错误,说明当前速率已经过高。退让,而不是强行推进。

关于更广泛的操作指南,请参阅如何不被封锁地抓取网站。如果你在跨多个话题大规模抓取新闻,大规模网络抓取涵盖了编排方面的内容,构建搜索引擎工具则展示了一旦你有了稳定的结构化结果流,可以搭建出什么样的应用。

抓取 Google News 是否合法?

抓取 Google News 是否被允许,取决于 Google 的服务条款、你所在的司法管辖区以及你对数据的使用方式,因此请将本文内容视为参考指导,而非法律建议。Google News 是一个聚合器:标题和摘要指向各个出版商自有的内容,Google 的条款对自动访问有所限制。此处的代码并不改变这一点,只是让技术层面运作起来。

有几条值得坚守的原则。仅收集公开结果:无需账户、任何人都能看到的标题、来源、时间戳和链接。检查 Google 的 robots.txt 并遵守其声明的速率预期,将请求量控制在不给任何人的服务器造成负担的范围内。不要转载或再分发完整文章文本,这属于原始出版商的版权内容。不要收集个人或私人数据。

本指南故意将范围限定在公开信息流数据,因为这是保持工作可辩护的边界。它不涵盖任何需要登录的内容、账户或个人信息、与可识别用户绑定的个性化信息流,或任何绕过身份验证的尝试。如果你的项目需要超出公开头条之外的内容,正确的做法是官方数据协议或授权的新闻 API,而不是更聪明的爬虫。

回顾

核心要点

  • Google News 是客户端渲染的。 普通请求返回近乎空白的框架,因此必须先渲染页面再解析。
  • Smart AI Proxy 提供渲染和可信 IP。 将你现有的 HTTP 客户端指向代理端点,以 token 为用户名,它就会在一步内完成 IP 轮换和页面渲染。
  • Cheerio 负责提取。 将标题、发布方、时间和作者映射到当前选择器,并预期这些选择器会随时间漂移。
  • 空白字段是正常的。 很多卡片没有作者信息,因此在下游将空字符串进行处理,而不是将其视为错误。
  • 仅针对公开数据。 遵守 Google 的服务条款和 robots.txt,不要抓取完整文章文本、个人数据或需要登录的信息流。

常见问题

为什么普通请求从 Google News 获取不到标题?

因为 Google News 通过 JavaScript 在客户端渲染其信息流。初始 HTML 是一个薄壳,只有页面脚本在浏览器中运行后才会填充,所以原始 HTTP 请求返回的是状态 200 加上空白的文章字段。要获取真实数据,必须先渲染页面,这正是通过 Smart AI Proxy 路由所处理的工作。

什么是 Crawlbase Smart AI Proxy?

Smart AI Proxy是一个直接替换的代理端点,通过大型住宅和数据中心 IP 池进行轮换,并在后台渲染页面。你保持使用普通 HTTP 客户端,只改变连接目标,以访问 token 作为代理用户名。它在内部转发到 Crawling API,因此你可以在不自行管理的情况下获得渲染和 IP 轮换能力。

对于 Google News,我应该用 Smart AI Proxy 还是 Crawling API?

两者到达的是相同的引擎,所以根据集成方式选择。Smart AI Proxy 对现有代码改动最小:设置代理主机、端口和 token,你当前的请求即可工作。Crawling API 是直接的 API 调用,你可以显式传入 JavaScript 渲染和等待时间等选项,当需要精细控制时更为方便。本指南使用代理方式,因为它对普通 axios 请求几乎不需要任何修改。

为什么输出中有些作者字段为空?

很多 Google News 卡片本身就没有署名,所以这些条目的作者选择器返回空字符串。这是预期行为,不是解析失败。根据你的任务需要,在下游通过过滤这些行、设置默认值或直接留空来处理它。

我的 Cheerio 选择器返回空字符串。发生了什么?

几乎可以肯定是 Google 的标记发生了变化。像 gPFEnUwIKyb 这样的哈希 class 名称会在没有通知的情况下变化,所以上个月有效的选择器可能已经失效。在浏览器开发者工具中重新检查实时结果页面并更新选择器。定期维护选择器对于任何生产爬虫来说都是正常的。

我可以用 Smart AI Proxy 抓取 Google News 以外的其他网站吗?

可以。Smart AI Proxy 是一个通用端点,同样的设置适用于大多数公开网站:修改目标 URL,并将选择器调整为新页面的结构即可。它的 IP 轮换和渲染能力对各种目标都有帮助,这与如何不被封锁地抓取网站中所涵盖的方法相同。

开始构建

大规模爬取任何站点,无需与基础设施对抗。

Crawlbase 负责处理代理、指纹和 CAPTCHA,让你的团队专注于交付数据流水线,而非维护爬取管道。1,000 次请求免费,无需信用卡。

自助开通 · 无需销售通话 · 提供企业级爬取量