SITCA 全名是超長的「證券投資信託暨顧問商業同業公會」,網站內有台灣全部境內基金的各種統計資料,不幸的是它沒開放 API 讓人查詢,所以只好來硬的…。
第一個要對付的叫做基金基本資料表,它長這樣:
簡單到不行的一個 form。
Version1
起初我天真的以為用 urllib
來對付它即可,不管用,吐不出資料來。
是 cookie 搞鬼嗎?不是,關掉 cookie 正常。
是 JavaScript 嗎?不是,關掉 JavaScript 也正常。
辛苦爬文之後找到 mechanize,它不只是抓抓網頁而已,它是更高階的模擬瀏覽器的行為,舉凡吃 cookie、騙 referrer、繞 robot.txt 都是拿手的。最後總算順利讓它吐資料出來:
import mechanize
URL = "https://www.sitca.org.tw/ROC/Industry/IN2105.aspx"
browser = mechanize.Browser()
browser.open(URL)
browser.select_form(name="aspnetForm")
response = browser.submit().read()
print(response)
吐出來的資料是 HTML 碼,需要再配合 parser 把資料萃取出來。
Version2
把它修改成用函式呼叫的方式,以及增加送出 select 表單的部分:
import mechanize
def scrape(url: str, form_name: str):
browser = mechanize.Browser()
browser.open(url)
browser.select_form(name=form_name)
browser["ctl00$ContentPlaceHolder1$ddlQ_Comid"] = ["A0003"] # 暫時只抓 A0003 第一金的資料簡化測試資料。
return browser.submit().read()
URL = "https://www.sitca.org.tw/ROC/Industry/IN2105.aspx"
FORM_NAME = "aspnetForm"
html = scrape(URL, FORM_NAME).decode('utf-8')
print(html)
看第 9 行,form 裡面的每個控制項都可以用 dict 的方式存取,dict 的 key 來自於網頁中表單控制項的 name
屬性:
這裡的範例送出的是 A0003
第一金投信。