News API无法获取指定公司新闻的问题求助与排查
问题分析与解决方案
核心原因
Berkshire Hathaway的名称包含空格,你手动拼接URL时未做URL编码,导致NewsAPI无法正确解析查询条件。未编码的空格会被服务器误判为参数分隔符,破坏整个查询逻辑,最终返回0条结果。
虽然你转义了Procter & Gamble的&,但带空格的名称同样需要编码,尤其是多个带空格名称组合时,未编码的空格会让服务器把查询字符串拆分成无效片段,直接导致查询失效。
验证逻辑
你移除Berkshire Hathaway后能正常返回结果,正是因为这个名称的空格未编码导致整个查询条件失效。单独测试少数带空格名称可能偶然生效,但多名称组合时,未编码空格会彻底打乱查询结构。
修复方案
不要手动拼接URL,改用requests的params参数自动处理编码,所有特殊字符(空格、&、括号等)都会被转为URL安全格式,确保服务器正确解析查询。
修改后的核心代码片段:
# 替换原URL拼接逻辑,用params字典管理参数 params = { 'q': " OR ".join(safe_company_tickers.keys()), 'from': today, 'to': today, 'language': 'en', 'sortBy': 'publishedAt', 'pageSize': 5, 'apiKey': 'my_api_key' } # 发送请求时传入params,自动处理编码 try: response = requests.get('https://newsapi.org/v2/everything', params=params) except Exception as exception: with open(f"{os.getcwd()}\\trader_log.log", "a") as log: log.write(f"[{datetime.datetime.now()}] Couldn't get news data. Error: {exception}.\n") exit()
额外优化建议
- SentimentIntensityAnalyzer初始化:把
sia = SentimentIntensityAnalyzer()移到循环外,避免重复初始化浪费资源。 - 公司匹配逻辑:当前找不到匹配公司就直接
exit(),会中断后续文章处理,建议改为跳过当前文章并记录日志,而非退出程序。 - 日期处理:用
datetime.date.today().isoformat()替代str(datetime.datetime.today()).split()[0],更简洁可靠。
优化后的完整代码:
import requests import json import os import datetime from nltk.sentiment import SentimentIntensityAnalyzer safe_company_tickers = {"Berkshire Hathaway": "BRK.B", "The Walt Disney Company": "DIS", "Vanguard High-Dividend Yield ETF": "VYM", "Procter & Gamble": "PG", "Vanguard Real Estate Index Fund": "VNQ", "Starbucks": "SBUX", "Apple": "AAPL", "Quest Diagnostics": "DGX", "Microsoft": "MSFT"} # 用ISO格式获取今日日期 today = datetime.date.today().isoformat() # 只初始化一次情感分析器 sia = SentimentIntensityAnalyzer() # 构建请求参数,自动处理编码 params = { 'q': " OR ".join(safe_company_tickers.keys()), 'from': today, 'to': today, 'language': 'en', 'sortBy': 'publishedAt', 'pageSize': 5, 'apiKey': 'my_api_key' } try: response = requests.get('https://newsapi.org/v2/everything', params=params) response.raise_for_status() # 主动抛出HTTP错误(如401、429) except Exception as exception: with open(f"{os.getcwd()}\\trader_log.log", "a") as log: log.write(f"[{datetime.datetime.now()}] Couldn't get news data. Error: {exception}.\n") exit() news = response.json() # 直接用response.json()解析返回值 for article in news["articles"]: print(article) # 分析情感,兼容description为空的情况 sentiment_scores = sia.polarity_scores(article.get("description", "")) print(sentiment_scores) # 匹配公司,同时检查title和description matched_company = None content = article.get("description", "") + article.get("title", "") for name in safe_company_tickers: if name in content: matched_company = name break if matched_company: print(f"Company's Ticker: {safe_company_tickers[matched_company]}") else: with open(f"{os.getcwd()}\\trader_log.log", "a") as log: log.write(f"[{datetime.datetime.now()}] 未匹配到指定公司的文章:{article['title']}.\n") continue # 跳过当前文章,继续处理下一篇
为什么手动拼接会出错?
手动拼接q=Berkshire Hathaway OR Apple时,URL中的空格未被编码,服务器会把Hathaway OR Apple当成无效参数,实际执行的查询是q=Berkshire,自然返回0条结果。而用params参数时,requests会自动把空格转为%20、&转为%26,确保查询逻辑完整传递给服务器。
内容的提问来源于stack exchange,提问作者MimisLovesToProgram
相关产品推荐
相关产品推荐

