SITCA 全名是超長的「證券投資信託暨顧問商業同業公會」,網站內有台灣全部境內基金的各種統計資料,不幸的是它沒開放 API 讓人查詢,所以只好來硬的…。

第一個要對付的叫做基金基本資料表,它長這樣:

SITCA

簡單到不行的一個 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 屬性:

HTML

這裡的範例送出的是 A0003 第一金投信。