Selenium 網路爬蟲教學:用 Selenium 到內政部不動產資訊平台抓法拍屋和金拍屋資料

PUBLISHED ON OCT 25, 2018 — WEB
FacebookTwitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    免責聲明:我們盡力確保本文的正確性,但本文不代表任何投資的建議,我們也無法擔保因使用本文的內容所造成的任何損失。如對本文內容有疑問,請詢問財經相關的專家。

    在這個範例中,我們會前往內政部不動產資訊平台的網站抓法拍屋和金拍屋資料。我們有兩種策略,一個是直接利用該頁面的輸出 Excel 連結來取得數據,一個是直接爬頁面上的資料以取得數據。前者比較簡單,所以在本範例中我們採取前者。

    我們這個爬蟲的動作拆解如下:

    1. 前往內政部不動產資訊平台中有關拍賣價格的頁面
    2. 拍賣有分法拍屋和金拍屋兩種,預設選項是全部,我們不調整
    3. 選取目標縣市,像是 新北市
    4. 選取目標鄉鎮市區,像是 板橋區
    5. 根據目前系統時間選擇三年內的時間,像本文完成於民國 107 年,就選 104
    6. 按下「查詢」鈕
    7. 按下「匯出 Excel」連結,取得資料

    請讀者實地操作一下,感受這個過程。這裡的三年沒有什麼特別的意義,只是假定太久以前的行情參考性較低,讀者可自行調整時距。

    由於整個程式碼較長,我們將其放在這裡;本文會拆解這個範例。

    先引入所需的套件:

    import datetime
    import os
    import time
    
    from selenium import webdriver
    

    將一些程式會用到的參數集中起來:

    targetCounty = "新北市"
    targetDistrict = "板橋區"
    now = datetime.datetime.now()
    threeYearAgo = str(now.year - 1911 - 3)
    downloadPath = os.path.dirname(os.path.abspath(__file__))
    

    雖然我們目前為了簡化範例,將參數的內容寫死在程式碼中。但我們保留日後將本程式參數化為命令列工具的彈性。

    設置 Chrome 瀏覽器的偏好設定:

    # Change Chrome options: (1) default downloading path, (2) disable popup blocking.
    options = webdriver.ChromeOptions()
    prefs = {}
    prefs["download.default_directory"] = downloadPath
    prefs["profile.default_content_settings"] = { "popups": 1 }
    options.add_experimental_option('prefs', prefs)
    

    在這裡我們設置可接受彈出視窗,這是因為在預設情形下,Chrome 會擋掉匯出的 Excel 文件。這個設置是經實測後修改的,不要死記這個設置。

    使用 Chrome 做為我們的 driver:

    # Create a new instance of the Chrome driver
    driver = webdriver.Chrome(chrome_options=options)
    

    前往相關頁面:

    # Go to the foreclosure house page.
    driver.get("https://pip.moi.gov.tw/V2/A/SCRA0601.aspx")
    time.sleep(6)  # Wait the page to fresh.
    

    一樣要讓網頁更新一下頁面,故暫停程式數秒鐘。

    選擇目標縣市:

    # Open the county menu.
    countyMenu = driver.find_element_by_css_selector("select[name=\"ctl00$ContentPlaceHolder1$ddlCity\"]")
    countyMenu.click()
    time.sleep(2)  # Wait the page to fresh.
    
    # Select targte county.
    countyOptions = driver.find_elements_by_css_selector("select[name=\"ctl00$ContentPlaceHolder1$ddlCity\"] option")
    for option in countyOptions:
        if targetCounty in option.text:
            option.click()
            break
    time.sleep(4)  # Wait the page to fresh.
    

    這個動作實際上分為兩步,一開始先開啟選單,接著選擇項目。

    選擇目標鄉鎮市區:

    # Open the district menu.
    districtMenu = driver.find_element_by_css_selector("select[name=\"ctl00$ContentPlaceHolder1$ddlTown\"]")
    districtMenu.click()
    time.sleep(2)  # Wait the page to fresh.
    
    # Select targte district.
    districtOptions = driver.find_elements_by_css_selector("select[name=\"ctl00$ContentPlaceHolder1$ddlTown\"] option")
    for option in districtOptions:
        if targetDistrict in option.text:
            option.click()
            break
    time.sleep(2)  # Wait the page to fresh.
    
    # Close district menu.
    districtMenu.click()
    time.sleep(2)  # Wait the page to fresh.
    

    這個動作可細分為三步,開啟選單、選擇目標項目、關閉選單。

    選擇起始年份:

    # Open the starting year menu.
    startYearMenu = driver.find_element_by_css_selector("select[name=\"ctl00$ContentPlaceHolder1$ddlYear1\"]")
    startYearMenu.click()
    time.sleep(2)  # Wait the page to fresh.
    
    # Select the starting year.
    startYears = driver.find_elements_by_css_selector("select[name=\"ctl00$ContentPlaceHolder1$ddlYear1\"] option")
    for option in startYears:
        if threeYearAgo in option.text:
            option.click()
            break
    time.sleep(2)  # Wait the page to fresh.
    
    # Close the starting year menu.
    startYearMenu.click()
    time.sleep(2)  # Wait the page to fresh.
    

    在此處,我們的想法是三年左右的行情有參考價值,讀者不一定要照我們的想法去寫程式。

    送出「查詢」按鈕:

    # Submit our query.
    submitButton = driver.find_element_by_css_selector("[name=\"ctl00$ContentPlaceHolder1$btnQuery\"]")
    submitButton.click()
    time.sleep(4)  # Wait the page to fresh.
    

    每次執行此程式會有一個新的檔案可下載,我們移掉舊的:

    # Remove old Excel file.
    excelPath = os.path.join(downloadPath, "%5b拍賣拍定價%5d查詢結果下載.xls")
    if os.path.exists(excelPath):
        os.remove(excelPath)
    

    下載此 Excel 檔:

    # Download new Excel file.
    link = driver.find_element_by_css_selector("#ctl00_ContentPlaceHolder1_btnExportExcel")
    link.click()
    time.sleep(5)  # Wait the page to fresh.
    

    最後不要忘了關掉瀏覽器:

    # Close the browser.
    driver.quit()
    
    TAGS: SELENIUM