台灣銀行牌告匯率爬蟲
import re
import requests
import pandas as pd
from bs4 import BeautifulSoup
### 設定網址
url = "https://rate.bot.com.tw/xrt"
### 舊版--失敗
# headers = {
# "User-Agent": "Mozilla/5.0"
# }
### 新版--成功
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/151.0.0.0 Safari/537.36"
),
"Accept": (
"text/html,application/xhtml+xml,application/xml;"
"q=0.9,image/avif,image/webp,*/*;q=0.8"
),
"Accept-Language": "zh-TW,zh;q=0.9,en;q=0.8"
}
### 發送 HTTP 請求
response = requests.get(
url,
headers=headers,
timeout=10
) # 向臺灣銀行網站發送 GET 請求,最多等待 10 秒
response.raise_for_status() # 如果請求失敗 (4xx、5xx),直接拋出例外
print("狀態碼:", response.status_code)
### 建立 BeautifulSoup
soup = BeautifulSoup(
response.text,
"lxml"
) # 將取得的 HTML 原始碼交給 BeautifulSoup 解析
### 抓取最新掛牌時間
time_element = soup.select_one(
".time"
)
if time_element:
update_time = time_element.get_text(
strip=True
)
else:
update_time = ""
print("最新掛牌時間:", update_time)
### 找到匯率表格中的所有資料列
rows = soup.select(
"table.table tbody tr"
) # 每一個 <tr> 代表一種外幣
print("幣別數量:", len(rows))
### 建立匯率資料串列
rate_list = []
### 逐列抓取匯率
for row in rows:
currency_element = row.select_one(
"td.currency div.hidden-phone" # 抓取電腦版的
) # 指定抓取 <div>,避免抓到沒有文字的 <br>
cash_rates = row.select(
"td.rate-content-cash"
)
sight_rates = row.select(
"td.rate-content-sight"
)
if not currency_element:
continue
currency_text = currency_element.get_text(
" ",
strip=True
) # 例如:美金 (USD)
match = re.match(
r"(.+?)\s*\(([A-Z]+)\)",
currency_text
)
if match:
currency_name = match.group(1).strip()
currency_code = match.group(2).strip()
else:
currency_name = currency_text
currency_code = ""
if len(cash_rates) >= 2:
cash_buy = cash_rates[0].get_text(strip=True)
cash_sell = cash_rates[1].get_text(strip=True)
else:
cash_buy = ""
cash_sell = ""
if len(sight_rates) >= 2:
sight_buy = sight_rates[0].get_text(strip=True)
sight_sell = sight_rates[1].get_text(strip=True)
else:
sight_buy = ""
sight_sell = ""
rate_list.append({
"幣別": currency_name,
"代碼": currency_code,
"現金買入": cash_buy,
"現金賣出": cash_sell,
"即期買入": sight_buy,
"即期賣出": sight_sell,
"掛牌時間": update_time
})
### 顯示匯率資料
print("\n臺灣銀行牌告匯率:")
for rate in rate_list:
print()
print("幣別:", rate["幣別"])
print("代碼:", rate["代碼"])
print("現金買入:", rate["現金買入"])
print("現金賣出:", rate["現金賣出"])
print("即期買入:", rate["即期買入"])
print("即期賣出:", rate["即期賣出"])
### 轉換成 DataFrame
rate_df = pd.DataFrame(rate_list)
print("\n匯率資料表:")
print(rate_df)
### 儲存成 CSV
rate_df.to_csv(
"臺灣銀行牌告匯率.csv",
index=False,
encoding="utf-8-sig"
) # 避免使用 Excel 開啟中文 CSV 時出現亂碼
### 執行完成
print("\n資料抓取完成")
print("共抓到:", len(rate_list), "種外幣")
print("已產生:臺灣銀行牌告匯率.csv")