Python 運行 Selenium 入門

這裡支援 Python 2.7, 3.4+

安裝 Driver

下載瀏覽器 driver ,請依照你瀏覽器目前的版本下載對應的 Driver

Chrome: https://sites.google.com/a/chromium.org/chromedriver/downloads
Edge: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Firefox: https://github.com/mozilla/geckodriver/releases
Safari: https://webkit.org/blog/6900/webdriver-support-in-safari-10/

在這裡,我們目前 Chrome 版本是 79.x,因此下載的是 chromedriver 79.x版本,

下載完成後,將 driver 放置環境變數,並且給予執行的權限

sudo cp chromedriver /usr/local/bin
sudo chmod +x /usr/local/bin/chromedriver

Python 安裝 selenium

安裝

pip install -U selenium
//or
pip3 install -U selenium

建立專案

vim test.py

建立爬蟲腳本,前往奇摩首頁,搜尋欄輸入 seleniumhq 後,送出搜尋

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

browser = webdriver.Chrome()

browser.get('http://www.yahoo.com')
assert 'Yahoo' in browser.title

elem = browser.find_element_by_name('p')  # Find the search box
elem.send_keys('seleniumhq' + Keys.RETURN)

browser.quit()

執行

sudo python test.py

透過 Chrome Seleinum IDE 快速建立腳本

在 Chrome 安裝擴充 Seleinum IDE

開啟 IDE,建立新 Project,接著點選 Rec

錄製完畢後,可以重複播放看看是否正確。

完成後,在左側專案的右邊 點擊三個點,出現選單

點選 Export 可選擇輸出腳本格式

輸出的腳本預設只有 class

可以自由應用,例如

# Generated by Selenium IDE
import pytest
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class TestTest():
  def setup_method(self, method):
    self.driver = webdriver.Chrome()
    self.vars = {}
  
  def teardown_method(self, method):
    self.driver.quit()
  
  def test_test(self):
    # Test name: test
    # Step # | name | target | value | comment
    # 1 | open | / |  | 
    self.driver.get("https://www.google.com/")
    # 2 | setWindowSize | 1256x900 |  | 
    self.driver.set_window_size(1256, 900)
    # 3 | click | name=q |  | 
    self.driver.find_element(By.NAME, "q").click()
    # 4 | type | name=q | adon988 | 
    self.driver.find_element(By.NAME, "q").send_keys("adon988")
    # 5 | sendKeys | name=q | ${KEY_ENTER} | 
    self.driver.find_element(By.NAME, "q").send_keys(Keys.ENTER)
    # 6 | click | css=div:nth-child(2) > .rc .LC20lb |  | 
    self.driver.find_element(By.CSS_SELECTOR, "div:nth-child(2) > .rc .LC20lb").click()
    # 7 | click | linkText=Mac 強制移除本地 mysql 佔用 3306,解決無法 kill 3306 process 問題 |  | 
    self.driver.find_element(By.LINK_TEXT, "Mac 強制移除本地 mysql 佔用 3306,解決無法 kill 3306 process 問題").click()
    # 8 | click | name=q |  | 
    self.driver.find_element(By.NAME, "q").click()
    # 9 | type | name=q | docker | 
    self.driver.find_element(By.NAME, "q").send_keys("docker")
    # 10 | sendKeys | name=q | ${KEY_ENTER} | 
    self.driver.find_element(By.NAME, "q").send_keys(Keys.ENTER)
  
a = TestTest()
a.setup_method('test')
a.test_test()

透過 Firefox 擴充套件 Katalon Recorder 快速建立腳本

開啟 Firefox ,至擴充套件安裝 Katalon Recorder

開啟擴充後,可以直接錄製腳本,接著點擊 Export 輸出腳本

腳本格式選擇 python2 (沒錯,目前只有 Python2)

例如:

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re

class UntitledTestCase(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(30)
        self.base_url = "https://www.google.com/"
        self.verificationErrors = []
        self.accept_next_alert = True
    
    def test_untitled_test_case(self):
        driver = self.driver
        driver.get("https://www.google.com.tw/")
        driver.find_element_by_name("q").click()
        driver.find_element_by_name("q").clear()
        driver.find_element_by_name("q").send_keys("adon988")
        driver.find_element_by_id("tsf").submit()
    
    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException as e: return False
        return True
    
    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException as e: return False
        return True
    
    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True
    
    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()

參考

https://learngeb-ebook.readbook.tw/intro/selenium.html

https://morvanzhou.github.io/tutorials/data-manipulation/scraping/5-01-selenium/