iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 13
0

昨天我們介紹了使用 requests 來取得網頁原始碼,可是有些透過 JavaScript 渲染的網頁或是防爬蟲做得很好的 ASP.Net 都會讓我們難以取得原始碼,這時候我們就可以用模擬瀏覽器來進行爬蟲,模擬瀏覽器就像是有一個人會一直依照你的指令操作瀏覽器的感覺,另一個情形是如果要做搶票或搶課這種連續性的動作,模擬瀏覽器可以真的模仿使用者在操作瀏覽器,而且自動連續點擊,方便且不易被伺服器端發現(?

Selenium 其實支援很多種程式語言,但今天我們是用 Python 來操作,他其實是個用來自動測試的套件,但可以被應用來爬蟲跟連點~


先建立今天要用的虛擬環境與安裝第三方套件 selenium

pipenv shell
pipenv install selenium

還必須要下載一個 browser driver 依照你安裝的瀏覽器要選擇不同 driver
Chrome: https://chromedriver.chromium.org/
Firefox: https://github.com/mozilla/geckodriver/releases

下載完後記住執行檔的路徑,等一下會需要用到


Selenium 基本操作語法

物件宣告

from selenium import webdriver

driverPath = r"C:\\chromedriver.exe" #填入剛剛記下的路徑
driver = webdriver.Chrome(driverPath) # Chrome
driver = webdriver.Firefox(driverPath) #Firefox

切換瀏覽器到目標網址

driver.get("http://www.google.com")

取得目前所在網頁的標題

print(driver.title)

以ID搜尋物件

from selenium.webdriver.common.by import By
element = driver.find_element(by=By.ID, value="TargetID")

以Name搜尋物件

from selenium.webdriver.common.by import By
obj = driver.find_element(By.NAME, "IamBanana")

以連結內容搜尋物件

from selenium.webdriver.common.by import By
obj = driver.find_element(By.LINK_TEXT, "https://rootttt.com.tw")

以CSS搜尋物件

from selenium.webdriver.common.by import By
obj = driver.find_element(By.CSS_SELECTOR, "#car span.blue.wow")

執行 JavaScript 指令碼

driver.execute_script("alert(1)")

執行 submit

driver.find_element_by_id("submit").click()

填入資料

driver.find_element_by_id("username").send_keys("USERNAME")

點擊按鈕

driver.find_element_by_id("buttom1").click()

切換視窗

driver.switch_to.window("windowName")

意外出現的彈出式視窗可能導致整個自動化腳本崩潰,我們可以用這種方式切換到視窗上進一步把他消掉

alert = driver.switch_to.alert
alert.text() #取得彈出式視窗內的文字
alert.dismiss() #關閉彈出式視窗

上一頁與下一頁

driver.back() #上一頁
driver.forward() #下一頁

重新整理

driver.fresh()

應用實例

看了上面各種語法之後,就可以利用你想要的動作完成一套自動化腳本來控制瀏覽器,讓他日以繼夜的加班工作(? 現在我們來看看一個應用實例。這是舊版台鐵的訂票模擬腳本,現在已經不能用了,所以我才敢放出來XD 不過大概應用實例就是這樣給大家參考一下。

注意!不要用這個去寫搶票程式,那樣違法,驗證碼一定要自己手動輸入,否則可能會有麻煩!!!

from selenium import webdriver
from selenium.webdriver.support.ui import Select
import time
import datetime 

"""
注意!僅需修改 User Config 內的資訊
其餘切勿做任何修改!
"""
#User Config
personid = "A123456789"
train_number = 105
count = 1
from_station_code = 100
to_station_code = 149
date = "2019/03/16"

#Script Config
Endpoint = "http://railway.hinet.net/Foreign/TW/etno1.html"

#----------Functions-------------#
def Date_gap(target_date_str):
    d1 = datetime.datetime.strptime(target_date_str,'%Y/%m/%d')
    d2 = datetime.datetime.now()

    days = ( d1 - d2 ).days
    days += 1

    if(days > 14):
        print("訂票只能訂兩星期以內的日期")
        exit()
    elif days < 0:
        print("日期輸入錯誤")
        exit()
    else:
        return days

#----------Script Start----------#
Date_gap(date)


browser = webdriver.Chrome()
browser.get(Endpoint)

bperson_id = browser.find_element_by_id("person_id")
btrain_number = browser.find_element_by_id("train_no")
bticket_count = Select( browser.find_element_by_id("order_qty_str"))
bfrom_station = Select( browser.find_element_by_id("from_station"))
bto_station = Select( browser.find_element_by_id("to_station"))
bdate = Select( browser.find_element_by_id("getin_date"))

bperson_id.send_keys(personid)
btrain_number.send_keys(str(train_number))
bticket_count.select_by_visible_text(str(count))
bfrom_station.select_by_value(str(from_station_code))
bto_station.select_by_value(str(to_station_code))
bdate.select_by_value(date+"-"+str(Date_gap(date)))

bsubmit = browser.find_element_by_class_name("btn-primary")
print(bsubmit)
bsubmit.submit()

brand_input = browser.find_element_by_id("randInput")
captcha = input("請手動輸入驗證碼->")
brand_input.send_keys(captcha)
brand_submit = browser.find_element_by_id("sbutton")
brand_submit.submit()

berror = browser.find_element_by_class_name("alert-danger")
berror_reason = browser.find_element_by_tag_name("strong")

print(berror_reason.text)

其實這就像一步一步流程寫下去,就像在寫劇本(? 很簡單,只是有時候會噴一些不明所以的錯誤,可能是因為瀏覽器載入速度比腳本慢,所以要是當的使用 time.sleep() 來等候瀏覽器完成,推薦各位一個好用的工具叫 Selenium IDE 他可以利用瀏覽器錄製的方式自動產生 Script,有時候真的挺方便的~

參考資料


https://www.seleniumhq.org/docs/03_webdriver.jsp


上一篇
Day12-網路爬蟲實作I 解析 html 檔案
下一篇
Day14-資料圖形化 Matplotlib 入門
系列文
原來電腦可以這樣用!? 果蠅也懂的程式語言教學30

尚未有邦友留言

立即登入留言