SITCA 的境內基金頁有台灣全部境內基金的各種統計資料,不幸的是它沒開放 API 讓人查詢,所以只好來硬的…。

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

SITCA

簡單到不行的一個 form。

Version1

起初我天真的以為用 urllib 來對付它即可,不管用,吐不出資料來。

是 cookie 搞鬼嗎?不是,關掉 cookie 正常;是 Javascript 嗎?不是,關掉 Javascript 也正常。

辛苦爬文之後找到 mechanize,它不只是抓抓網頁而已,它是更高階的模擬瀏覽器的行為,舉凡吃 cookie、騙 referrer、繞 robot.txt 都是拿手的。最後總算順利讓它吐資料出來:

#! /usr/bin/env python2.7

from __future__ import print_function

import mechanize
 
url = "http://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 把資料萃取出來。

mechanize 也不是萬能的,它目前不相容於 Python3,而且沒有「良好的」文件只有範例。

下一步是萃取資料。

Version2

把它修改成用函式呼叫的方式,以及增加送出 select 表單的部分:

#! /usr/bin/eny python2.7
 
from __future__ import print_function
import mechanize
import lxml.html
import scraperwiki
 
def scrape(url, form_name):
    browser = mechanize.Browser()
    browser.open(url)
    browser.select_form(name=form_name)
    browser["ctl00$ContentPlaceHolder1$ddlQ_Comid"] = ["A0003"] # 暫時只抓 A003 第一金的資料簡化測試資料,測試後取消。
    return browser.submit().read()
 
url = "http://www.sitca.org.tw/ROC/Industry/IN2105.aspx"
form_name = "aspnetForm"
html = scrape(url, form_name).decode('utf-8')
print(html)

看第 12 行,browserform 裡面的每個控制項都可以用 dict 的方式存取,dict 的 key 來自於網頁中表單控制項的 name 屬性:

HTML

這裡的範例送出的是 A0003