Sooteemon commited on
Commit
bf00b84
·
verified ·
1 Parent(s): d5e84de

Update scraper.py

Browse files
Files changed (1) hide show
  1. scraper.py +59 -108
scraper.py CHANGED
@@ -1,96 +1,66 @@
1
  import requests
2
- from bs4 import BeautifulSoup
3
- import feedparser
4
- from datetime import datetime
5
- import time
 
 
 
6
 
7
  class YahooFinanceScraper:
8
  def __init__(self):
 
9
  self.headers = {
10
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
11
  }
12
- self.base_url = "https://finance.yahoo.com"
13
-
14
- def get_latest_news(self, symbol="", max_articles=10):
15
- """
16
- ดึงข่าวล่าสุดจาก Yahoo Finance
17
-
18
- Args:
19
- symbol: ticker symbol (เช่น AAPL, TSLA) หรือเว้นว่างสำหรับข่าวทั่วไป
20
- max_articles: จำนวนข่าวที่ต้องการ
21
-
22
- Returns:
23
- list: รายการข่าว [{title, link, summary, published}]
24
- """
25
  news_list = []
26
-
27
- try:
28
- if symbol:
29
- # ดึงข่าวเฉพาะหุ้น
30
- url = f"{self.base_url}/quote/{symbol}"
31
- response = requests.get(url, headers=self.headers, timeout=10)
32
- soup = BeautifulSoup(response.content, 'html.parser')
33
-
34
- # หา news section
35
- news_items = soup.find_all('li', class_='stream-item', limit=max_articles)
36
-
37
- for item in news_items:
38
- try:
39
- title_tag = item.find('h3')
40
- link_tag = item.find('a')
41
- summary_tag = item.find('p')
42
- time_tag = item.find('time')
43
-
44
- if title_tag and link_tag:
45
- news_list.append({
46
- 'title': title_tag.get_text(strip=True),
47
- 'link': link_tag.get('href', ''),
48
- 'summary': summary_tag.get_text(strip=True) if summary_tag else '',
49
- 'published': time_tag.get_text(strip=True) if time_tag else 'N/A'
50
- })
51
- except Exception as e:
52
- continue
53
-
54
- else:
55
- # ดึงข่าวทั่วไปผ่าน RSS Feed
56
- rss_url = "https://finance.yahoo.com/news/rssindex"
57
- feed = feedparser.parse(rss_url)
58
-
59
- for entry in feed.entries[:max_articles]:
60
- news_list.append({
61
- 'title': entry.get('title', 'No title'),
62
- 'link': entry.get('link', ''),
63
- 'summary': entry.get('summary', '')[:300], # จำกัด 300 ตัวอักษร
64
- 'published': entry.get('published', 'N/A')
65
- })
66
-
67
- # ถ้าไม่มีข่าว ลองวิธีสำรอง
68
- if not news_list:
69
- news_list = self._get_fallback_news(max_articles)
70
-
71
- except Exception as e:
72
- print(f"Error scraping news: {e}")
73
- news_list = self._get_fallback_news(max_articles)
74
-
75
- return news_list
76
-
77
- def _get_fallback_news(self, max_articles):
78
- """วิธีสำรองในกรณีที่ดึงข่าวไม่ได้"""
79
  try:
80
- # ใช้ Yahoo Finance RSS feed แบบง่าย
81
- url = "https://finance.yahoo.com/rss/topstories"
82
- feed = feedparser.parse(url)
83
 
84
- news_list = []
85
  for entry in feed.entries[:max_articles]:
86
  news_list.append({
87
  'title': entry.get('title', 'No title'),
88
- 'link': entry.get('link', ''),
89
- 'summary': entry.get('summary', '')[:300],
 
90
  'published': entry.get('published', 'N/A')
91
  })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
- return news_list
 
 
 
 
 
 
 
 
 
 
 
 
94
  except:
95
  return [{
96
  'title': 'Unable to fetch news',
@@ -98,43 +68,24 @@ class YahooFinanceScraper:
98
  'summary': 'Please try again later',
99
  'published': 'N/A'
100
  }]
101
-
102
  def search_news(self, keyword, max_articles=10):
103
  """
104
- ค้นหาข่าวด้วย keyword
105
-
106
- Args:
107
- keyword: คำค้นหา
108
- max_articles: จำนวนข่าว
109
-
110
- Returns:
111
- list: รายการข่าวที่เกี่ยวข้อง
112
  """
113
- try:
114
- search_url = f"{self.base_url}/search?p={keyword}"
115
- response = requests.get(search_url, headers=self.headers, timeout=10)
116
- soup = BeautifulSoup(response.content, 'html.parser')
117
 
118
- news_list = []
119
- articles = soup.find_all('div', class_='Ov(h)', limit=max_articles)
 
 
120
 
121
- for article in articles:
122
- try:
123
- title = article.find('h3')
124
- link = article.find('a')
125
-
126
- if title and link:
127
- news_list.append({
128
- 'title': title.get_text(strip=True),
129
- 'link': link.get('href', ''),
130
- 'summary': '',
131
- 'published': 'Recent'
132
- })
133
- except:
134
- continue
135
 
136
- return news_list if news_list else self.get_latest_news(max_articles=max_articles)
 
137
 
138
  except Exception as e:
139
  print(f"Search error: {e}")
140
- return self.get_latest_news(max_articles=max_articles)
 
1
  import requests
2
+ import feedparser # เราจะใช้ feedparser เป็นหลัก
3
+ from urllib.parse import quote # ใช้สำหรับเข้ารหัส keyword
4
+
5
+ # --- ไม่จำเป็นต้องใช้ BeautifulSoup อีกต่อไป ---
6
+ # from bs4 import BeautifulSoup
7
+ # import time
8
+ # from datetime import datetime
9
 
10
  class YahooFinanceScraper:
11
  def __init__(self):
12
+ # User-Agent ยังคงมีประโยชน์
13
  self.headers = {
14
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
15
  }
16
+ # base_url ไม่จำเป็นต้องใช้อีกต่อไป
17
+ # self.base_url = "https://finance.yahoo.com"
18
+
19
+ def _parse_feed(self, url, max_articles=10):
20
+ """ฟังก์ชันช่วยในการดึงและแปลง RSS feed"""
 
 
 
 
 
 
 
 
21
  news_list = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  try:
23
+ # feedparser สามารถรับ URL และ User-Agent ได้โดยตรง
24
+ feed = feedparser.parse(url, agent=self.headers['User-Agent'])
 
25
 
 
26
  for entry in feed.entries[:max_articles]:
27
  news_list.append({
28
  'title': entry.get('title', 'No title'),
29
+ # ลิงก์จาก Google News RSS มักจะพาไปหน้า Google ก่อน เราจึงต้อง clean มัน
30
+ 'link': entry.get('link', '').split('&url=')[-1],
31
+ 'summary': entry.get('summary', '')[:300], # จำกัด 300 ตัวอักษร
32
  'published': entry.get('published', 'N/A')
33
  })
34
+ except Exception as e:
35
+ print(f"Error parsing feed: {e}")
36
+ return self._get_fallback_news(1) # ถ้าพัง ให้ไปที่ fallback
37
+
38
+ return news_list
39
+
40
+ def get_latest_news(self, symbol="", max_articles=10):
41
+ """
42
+ ดึงข่าวล่าสุดจาก Yahoo Finance (แก้ไขใหม่ให้ใช้ RSS เสมอ)
43
+ """
44
+ if symbol:
45
+ # (เสถียร) ใช้ RSS feed สำหรับหุ้นนั้นๆ
46
+ url = f"https://finance.yahoo.com/rss/quotes/{symbol.upper()}"
47
+ else:
48
+ # (เสถียร) ใช้ RSS feed ข่าวทั่วไป
49
+ url = "https://finance.yahoo.com/news/rssindex"
50
 
51
+ news_list = self._parse_feed(url, max_articles)
52
+
53
+ # ถ้าดึงข่าวหุ้นแล้วไม่เจอ (เช่น พิมพ์ผิด) ให้ลอง fallback
54
+ if symbol and not news_list:
55
+ return self._get_fallback_news(max_articles)
56
+
57
+ return news_list
58
+
59
+ def _get_fallback_news(self, max_articles):
60
+ """วิธีสำรองในกรณีที่ดึงข่าวไม่ได้ (ใช้ Top Stories feed)"""
61
+ try:
62
+ url = "https://finance.yahoo.com/rss/topstories"
63
+ return self._parse_feed(url, max_articles)
64
  except:
65
  return [{
66
  'title': 'Unable to fetch news',
 
68
  'summary': 'Please try again later',
69
  'published': 'N/A'
70
  }]
71
+
72
  def search_news(self, keyword, max_articles=10):
73
  """
74
+ ค้นหาข่าวด้วย keyword (แก้ไขใหม่ให้ใช้ Google News RSS ซึ่งเสถียรกว่ามาก)
 
 
 
 
 
 
 
75
  """
76
+ if not keyword:
77
+ return self.get_latest_news(max_articles=max_articles) # ถ้าไม่ใส่ keyword ก็ไปข่าวล่าสุด
 
 
78
 
79
+ try:
80
+ # (เสถียรมาก) ใช้ Google News RSS ค้นหาเฉพาะในเว็บ finance.yahoo.com
81
+ safe_keyword = quote(keyword)
82
+ url = f"https://news.google.com/rss/search?q={safe_keyword}+site:finance.yahoo.com&hl=en-US&gl=US&ceid=US:en"
83
 
84
+ news_list = self._parse_feed(url, max_articles)
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
+ # ถ้า Google News ค้นไม่เจอ ให้ลอง fallback
87
+ return news_list if news_list else self._get_fallback_news(max_articles)
88
 
89
  except Exception as e:
90
  print(f"Search error: {e}")
91
+ return self._get_fallback_news(max_articles)