news.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import os
  2. import requests
  3. from snownlp import SnowNLP
  4. import smtplib
  5. from email.message import EmailMessage
  6. from datetime import datetime
  7. # Configuration
  8. NEWS_API_KEY = os.getenv('NEWS_API_KEY') # Get from https://newsapi.org
  9. EMAIL_ADDRESS = os.getenv('EMAIL_ADDRESS')
  10. EMAIL_PASSWORD = os.getenv('EMAIL_PASSWORD')
  11. SEARCH_TERMS = "新能源 OR IPO OR 电动汽车 IPO OR 中国汽车"
  12. # def fetch_news():
  13. # """Fetch Chinese news articles about new energy/car IPOs"""
  14. # url = 'https://newsapi.org/v2/everything'
  15. # params = {
  16. # 'q': SEARCH_TERMS,
  17. # 'language': 'zh',
  18. # 'sortBy': 'publishedAt',
  19. # 'apiKey': NEWS_API_KEY,
  20. # 'pageSize': 20
  21. # }
  22. # print(f"NEWS_API_KEY: {NEWS_API_KEY}")
  23. # response = requests.get(url, params=params)
  24. # response.raise_for_status()
  25. # return response.json().get('articles', [])
  26. def fetch_news():
  27. """Fetch top headlines about new energy/car IPOs in China and Hong Kong"""
  28. url = 'https://newsapi.org/v2/top-headlines'
  29. params = {
  30. 'q': SEARCH_TERMS,
  31. 'language': 'zh',
  32. 'apiKey': NEWS_API_KEY,
  33. 'pageSize': 20,
  34. 'country': 'cn', # Country code for China
  35. # 'country': 'hk', # Uncomment this line to switch to Hong Kong
  36. }
  37. print(f"NEWS_API_KEY: {NEWS_API_KEY}")
  38. response = requests.get(url, params=params)
  39. response.raise_for_status()
  40. print(f"Complete URL for testing: {response.request.url}")
  41. print(f"Request Params: {params}")
  42. print(f"Response Status Code: {response.status_code}")
  43. print(f"Response Content: {response.text}")
  44. return response.json().get('articles', [])
  45. def analyze_articles(articles):
  46. """Analyze sentiment and filter relevant news"""
  47. processed = []
  48. for article in articles:
  49. content = f"{article['title']}. {article['description']}"
  50. sentiment = SnowNLP(content).sentiments
  51. # Filter criteria (adjust as needed)
  52. if any(keyword in content for keyword in ["IPO", "上市", "申购"]) and sentiment >= 0.4:
  53. processed.append({
  54. 'title': article['title'],
  55. 'url': article['url'],
  56. 'source': article['source']['name'],
  57. 'date': article['publishedAt'],
  58. 'sentiment': round(sentiment, 2)
  59. })
  60. return processed
  61. def send_notification(articles, debug_mode=True):
  62. """Send alerts to console (debug) or email (production)"""
  63. if not articles:
  64. return
  65. if debug_mode:
  66. # Console output version
  67. print(f"\n=== IPO Alerts ({datetime.now().strftime('%Y-%m-%d %H:%M')}) ===")
  68. for idx, article in enumerate(articles, 1):
  69. print(f"{idx}. {article['title']}")
  70. print(f" Source: {article['source']}")
  71. print(f" Sentiment: {article['sentiment']}")
  72. print(f" URL: {article['url']}")
  73. print(f" Date: {article['date']}\n{'-'*50}")
  74. else:
  75. # Original email version (kept for reference)
  76. msg = EmailMessage()
  77. msg['Subject'] = f"新能源IPO警报 - {datetime.now().strftime('%Y-%m-%d %H:%M')}"
  78. msg['From'] = EMAIL_ADDRESS
  79. msg['To'] = EMAIL_ADDRESS
  80. email_body = "发现重要IPO相关新闻:\n\n"
  81. for idx, article in enumerate(articles, 1):
  82. email_body += f"""【{idx}】{article['title']}
  83. - 来源: {article['source']}
  84. - 情绪值: {article['sentiment']}
  85. - 链接: {article['url']}
  86. - 时间: {article['date']}
  87. \n"""
  88. msg.set_content(email_body)
  89. with smtplib.SMTP('smtp.gmail.com', 587) as server:
  90. server.starttls()
  91. server.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
  92. server.send_message(msg)
  93. def main():
  94. # Step 1: Fetch news
  95. articles = fetch_news()
  96. # Step 2: Analyze content
  97. filtered_articles = analyze_articles(articles)
  98. # Step 3: Send notification (debug mode to console)
  99. if filtered_articles:
  100. send_notification(filtered_articles, debug_mode=True)
  101. print(f"Found {len(filtered_articles)} relevant articles")
  102. else:
  103. print("No significant updates found")
  104. if __name__ == "__main__":
  105. main()