動態網頁有別於靜態網頁產生資料的方式。靜態網頁是透過每一次使用者請求,後端會產生一次網頁回傳,所以請求與回傳是一對一的,有些人把他們稱為同步。在動態網頁的話,是透過 Ajax 的技術,來完成非同步的資料傳輸。換句話說,就是在網頁上,任何時間點都可以發送請求給後端,後端只回傳資料,而不是回傳整個網頁。這樣一來,就不是一對一的關係,在處理資料上就會比較麻煩。所以我們換個角度,原本是模擬瀏覽器的動作,現在我們直接模擬人的操作。
這次使用 Selenium 實作 Data Crawler,Selenium 主要是拿來模擬瀏覽器行為的工具,而我們也利用的功能,模擬使用者瀏覽資料的過程取得資料,進一步利用 beautifulsoup 將原始資料進行爬梳。
from selenium import webdriver
from selenium.webdriver.support.ui import Select
# 開啟網頁
browser.get("http://taqm.epa.gov.tw/taqm/tw/MonthlyAverage.aspx")
# 模擬行為
selectSite = Select(browser.find_element_by_id("ctl15_ddlSite"))
selectSite.select_by_value(cite)
selectYear = Select(browser.find_element_by_id("ctl15_ddlYear"))
selectYear.select_by_value(str(year))
browser.find_element_by_id('ctl15_btnQuery').click()
# 取得資料
html_source = browser.page_source
# 關閉瀏覽器
browser.quit();
接著,urllib.urlopen() 回傳的資料就是我們想要的網頁。不過當你讀他的時候會發現好像是亂碼一樣,不過放心,這是正確的。我們前面有說過,一般網頁是因為透過瀏覽器重新編碼才會到你眼前。所以你現在看的資料是沒有經過瀏覽器的原始資料。下一步就是要重這個充滿 HTML 標籤的資料中,整理出我們想要的部分。
from bs4 import BeautifulSoup
# 取得資料進行整理
soup = BeautifulSoup(html_source, 'html.parser')
city = soup.find(id="ctl15_ddlSite").find_all('option', selected=True)[0].