如何用Python抓取Google News特定年份(如2020年)的新闻标题及相关信息
如何用Python抓取Google News特定年份(如2020年)的新闻标题及相关信息
嘿,我完全懂你的困扰!Google News的RSS接口确实有局限性,它默认只返回近期的热门内容,根本没法直接指定年份过滤——这就是为什么你用原有代码抓不到2020年的旧新闻,而网页端滚动能看到,是因为网页用了动态加载的后端接口,RSS根本对接不到那部分数据。下面给你几个可行的解决思路和代码示例:
一、为什么原有RSS方法不生效?
Google News的RSS搜索接口https://news.google.com/rss/search没有公开的参数支持指定年份范围,它默认只返回最近数天/数周的内容,完全触达不到2020年这类历史新闻数据。网页端能加载旧内容,是因为它调用了不同的动态接口,和RSS不是一套体系。
二、解决方案1:构造时间过滤的网页搜索URL,用BeautifulSoup解析
我们可以直接利用Google News的高级搜索语法,构造包含年份范围的搜索URL,然后用requests模拟浏览器请求,再用BeautifulSoup解析网页内容。
代码示例:
import requests from bs4 import BeautifulSoup import pandas as pd from datetime import datetime import time class GoogleNewsYearScraper: def __init__(self, query, target_year): self.query = query self.target_year = target_year # 设定目标年份的时间范围:1月1日到12月31日 self.start_date = f"{target_year}-01-01" self.end_date = f"{target_year}-12-31" # 模拟浏览器请求头,避免被Google拦截 self.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" } self.base_url = "https://news.google.com/search" def scrape_single_page(self, page=0): # 构造带时间过滤的搜索参数,page控制分页(每10条为一页) search_params = { "q": f"{self.query} after:{self.start_date} before:{self.end_date}", "hl": "en-IN", "gl": "IN", "ceid": "IN:en", "start": page * 10 } response = requests.get(self.base_url, params=search_params, headers=self.headers) if response.status_code != 200: print(f"请求失败,状态码:{response.status_code}") return [] soup = BeautifulSoup(response.text, "html.parser") articles = soup.find_all("article") page_data = [] for article in articles: # 提取标题 title_tag = article.find("h3") title = title_tag.get_text(strip=True) if title_tag else "无标题" # 提取并转换真实链接(处理Google的内部跳转链接) link_tag = title_tag.find("a") if title_tag else None link = f"https://news.google.com{link_tag['href']}" if (link_tag and link_tag['href'].startswith("/")) else "无链接" # 提取发布日期 date_tag = article.find("time") if date_tag: date_obj = datetime.fromisoformat(date_tag["datetime"].replace("Z", "+00:00")) formatted_date = date_obj.strftime("%Y-%m-%d") else: formatted_date = "无日期" page_data.append({ "Title": title, "URL link": link, "Date": formatted_date }) return page_data def scrape_all_pages(self, max_pages=5): all_news_data = [] for page_num in range(max_pages): print(f"正在抓取第{page_num+1}页...") current_page_data = self.scrape_single_page(page_num) if not current_page_data: break # 没有更多内容就停止抓取 all_news_data.extend(current_page_data) time.sleep(2) # 加延迟,避免触发反爬机制 return all_news_data def save_to_csv(self): all_data = self.scrape_all_pages() df = pd.DataFrame(all_data) csv_filename = f"{self.query.replace(' ', '_')}_{self.target_year}.csv" df.to_csv(csv_filename, index=False) print(f"数据已成功保存到 {csv_filename}") if __name__ == "__main__": search_query = "forex rate news" target_year = 2020 scraper = GoogleNewsYearScraper(search_query, target_year) scraper.save_to_csv()
代码说明:
- 用Google搜索的高级语法
after:和before:精准锁定2020年的时间范围 - 模拟浏览器的
User-Agent,降低被拦截的概率 - 支持分页抓取,你可以调整
max_pages参数控制抓取的页数 - 自动把Google的内部跳转链接转换为真实新闻链接
三、解决方案2:使用第三方库GoogleNews
如果你不想自己写网页解析逻辑,可以用现成的GoogleNews库,它封装了Google News的接口,能直接支持时间范围过滤。
操作步骤:
- 先安装库:
pip install GoogleNews
- 代码示例:
from GoogleNews import GoogleNews import pandas as pd from datetime import datetime class GoogleNewsLibraryScraper: def __init__(self, query, target_year): self.query = query self.start_date = f"{target_year}-01-01" self.end_date = f"{target_year}-12-31" # 初始化GoogleNews对象,设置语言和地区 self.gn = GoogleNews(hl='en-IN', gl='IN') self.gn.set_time_range(self.start_date, self.end_date) def scrape_news(self, max_pages=5): self.gn.search(self.query) all_news_data = [] for page_num in range(max_pages): print(f"正在抓取第{page_num+1}页...") page_results = self.gn.page_at(page_num+1) # 库的分页从1开始计数 if not page_results: break for result in page_results: # 处理日期格式:尝试转换为标准日期,失败则保留原字符串 try: date_obj = datetime.strptime(result["date"], "%b %d, %Y") formatted_date = date_obj.strftime("%Y-%m-%d") except ValueError: formatted_date = result["date"] all_news_data.append({ "Title": result["title"], "URL link": result["link"], "Date": formatted_date, "Summary": result["desc"] # 额外提取新闻摘要 }) return all_news_data def save_to_csv(self): all_data = self.scrape_news() df = pd.DataFrame(all_data) csv_filename = f"{self.query.replace(' ', '_')}_{self.target_year}.csv" df.to_csv(csv_filename, index=False) print(f"数据已成功保存到 {csv_filename}") if __name__ == "__main__": search_query = "forex rate news" target_year = 2020 scraper = GoogleNewsLibraryScraper(search_query, target_year) scraper.save_to_csv()
注意事项:
GoogleNews库有时会返回相对时间(比如"2 years ago"),如果需要精确的2020年日期,可能需要额外处理,或者结合第一种网页解析的方式- 第三方库可能会随着Google News界面更新而失效,记得定期检查版本更新
四、重要提醒
- Google有严格的反爬机制,不要过于频繁地发送请求,建议每次请求之间加2-5秒的延迟
- 如果遇到验证码或被封禁,可以尝试更换
User-Agent,或者使用代理(注意合规) - 确保你的抓取行为符合Google的服务条款,不要用于大规模商业爬取
备注:内容来源于stack exchange,提问作者Charmi Divecha




