Python爬蟲4.3 — selenium基礎用法教程

綜述

本系列文檔用於對Python爬蟲技術的學習進行簡單的教程講解,鞏固自己技術知識的同時,萬一一不小心又正好對你有用那就更好了。
Python 版本是3.7.4

在前一章中,我們瞭解了Ajax的分析和抓取方式,這其實也是JavaScript動態渲染的頁面的一種情形,通過直接分析Ajax,我們仍然可以藉助requests或urllib來實現數據爬取。

不過JavaScript動態渲染的頁面不止Ajax這一種。例如淘寶這種頁面,它即使是Ajax獲取的數據,但是其Ajax接口含有很多加密參數,我們難以直接找出其規律,也很難直接分析Ajax來抓取。

爲了解決這些問題,我們可以直接使用模擬瀏覽器運行的方式來實現,這樣就可以做到在瀏覽器中看到是什麼樣,抓取的源碼就是什麼樣,也就是可見即可爬。這樣我們就不用再去管網頁內部的JavaScript用了什麼算法渲染頁面,不用管網頁後臺的Ajax接口到底有哪些參數。

Python提供了許多模擬瀏覽器運行的庫,如Selenium、Splash、PyV8、Ghost等。本章中,我們就來介紹一下Selenium的用法。Selenium+chromedriver(Headless Chrome)可以稱爲爬蟲的終極解決方案。

Selenium + Chromedriver

Selenium 介紹

Selenium是一個自動化測試工具,利用它可以驅動瀏覽器執行特定的動作,如點擊、下拉等操作,同時還可以獲取瀏覽器當前呈現的頁面的源代碼,做到可見即可爬。對於一些JavaScript動態渲染的頁面來說,此種抓取方式非常有效。

可以將Selenium理解相當於一個機器人,可以模擬人類在瀏覽器上的一切行爲,自動處理瀏覽器上的一些行爲。

Chromedriver 介紹

Chromedriver是一個驅動Chrome瀏覽器的驅動程序,使用它纔可以驅動瀏覽器。

Headless Chrome在Chrome59中開始搭載HeadlessChrome。這是一種在無需顯示headless的環境下運行Chrom瀏覽器的方式。從本質上來說,就是不用chrome瀏覽器來運行Chrome的功能!

自從SeleniumPhantomJS"分手"之後,使用Selenium+Headless Chrome成爲主流。

其他瀏覽器的driver

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

安裝Selenium+chromedriver

  1. 安裝SeleniumSelenium有很多語言的版本,有java、ruby、python等。我們使用pip安裝python版本即可:
    $ pip install selenium
  1. 安裝chromedriver:下載相應的chromedriver放到不需要權限的純英文目錄下就可以了。版本號對應描述:http://chromedriver.storage.googleapis.com/2.40/notes.txt

簡單使用

獲取百度首頁

現在我們以一個簡單的獲取百度首頁的例子來講下Seleniumchromedriver如何快速入門,示例代碼如下:

# 引入所需庫
from selenium import webdriver

# 聲明定義chromedriver路徑
path = r'E:\Python_Code\s1\chromedriver_win32\chromedriver.exe'
# 實例化Chrome
# 如果時其他瀏覽器需要實例化爲對應的對象,例如火狐webdriver.firefox()
driver = webdriver.Chrome(path)
# 打開百度
driver.get('https://www.baidu.com/')
# 獲取源碼
print(driver.page_source)
# 關閉
driver.close()

Selenium常用操作

更多教程請參考:https://python-selenium-zh.readthedocs.io/zh_CN/latest/

關閉頁面

  1. driver.close() : 關閉當前頁面。
  2. driver.quit() : 退出整個瀏覽器。

示例代碼如下:

# 引入所需庫
import time
from selenium import webdriver

# 聲明定義chromedriver路徑
path = r'E:\Python_Code\s1\chromedriver_win32\chromedriver.exe'
# 實例化Chrome
# 如果時其他瀏覽器需要實例化爲對應的對象,例如火狐webdriver.firefox()
driver = webdriver.Chrome(path)
# 打開百度
driver.get('https://www.baidu.com/')
time.sleep(5)
# 關閉當前頁面
driver.close()
# 關閉瀏覽器
driver.quit()

定位元素

  1. find_element_by_id : 根據id來查找某個元素。等價於:
    input_kw = driver.find_element_by_id('kw')
    input_kw = driver.find_element(By.ID, 'kw')
    
  2. find_element_by_class_name : 根據類名查找元素,等價於:
    input_kw = driver.find_element_by_class_name('s_ipt')
    input_kw = driver.find_element(By.CLASS_NAME, 's_ipt')
    
  3. find_element_by_name : 根據name屬性的值來查找元素,等價於:
    input_kw = driver.find_element_by_name('wd')
    input_kw = driver.find_element(By.ID, 'wd')
    
  4. find_element_by_tag_name : 根據標籤名來查找元素,等價於:
    input_kw = driver.find_element_by_tag_name('input')
    input_kw = driver.find_element(By.TAG_NAME, 'input')
    
  5. find_element_by_xpath : 根據xpath語法來獲取元素,等價於:
    input_kw = driver.find_element_by_xpath('//input[@id="kw"]')
    input_kw = driver.find_element(By.XPATH, '//input[@id="kw"]')
    
    使用selenium中xpath獲取元素屬性值得時候和真實的xpath語法有些不同,例如獲取a標籤的href屬性值,在真實的xpath語法中使用//a[@seed="bankcard-more"]/@href即可,但是在selenium中這樣使用會報錯;只能使用//a[@seed="bankcard-more"]先獲取標籤元素,然後使用get_attribute("href")獲取屬性值,例如:
    bank_url_ele = driver.find_element_by_xpath('//a[@seed="bankcard-more"]')
    bank_url = bank_url_ele.get_attribute("href")
    
  6. find_element_by_css_selector : 根據css選擇器來選擇元素,等價於:
    input_kw = driver.find_element_by_css_selector('.s_ipt')
    input_kw = driver.find_element(By.CSS_SELECTOR, '.s_ipt')
    

使用示例代碼如下:

# 引入所需庫
import time

from selenium import webdriver
from selenium.webdriver.common.by import By

# 聲明定義chromedriver路徑
path = r'E:\Python_Code\s1\chromedriver_win32\chromedriver.exe'
# 實例化Chrome
# 如果時其他瀏覽器需要實例化爲對應的對象,例如火狐webdriver.firefox()
driver = webdriver.Chrome(path)
# 打開百度
driver.get('https://www.baidu.com/')
time.sleep(2)
# 根據id獲取元素
# input_kw = driver.find_element_by_id('kw')
# input_kw = driver.find_element(By.ID, 'kw')

# 根據類名獲取元素
# input_kw = driver.find_element_by_class_name('s_ipt')
# input_kw = driver.find_element(By.CLASS_NAME, 's_ipt')

# 根據name屬性值來獲取元素
# input_kw = driver.find_element_by_name('wd')
# input_kw = driver.find_element(By.NAME, 'wd')

# 根據標籤名來獲取元素
# input_kw = driver.find_element_by_tag_name('input')
# input_kw = driver.find_element(By.TAG_NAME, 'input')

# 根據xpath語法獲取元素
# input_kw = driver.find_element_by_xpath('//input[@id="kw"]')
# input_kw = driver.find_element(By.XPATH, '//input[@id="kw"]')

# 根據css選擇器來選擇元素
input_kw = driver.find_element_by_css_selector('.s_ipt')
# input_kw = driver.find_element(By.CSS_SELECTOR, '.s_ipt')
print(input_kw)

# 獲取全部符合元素
# inputs_kw = driver.find_elements_by_css_selector('.s_ipt')[0]
inputs_kw = driver.find_elements(By.CSS_SELECTOR, '.s_ipt')

print(inputs_kw)
time.sleep(2)
# 關閉當前頁面
driver.close()

注意:
1. find_element_獲取第一個符合條件的元素。find_elements_是獲取所有滿足條件的元素。
2.如果知識想要解析網頁中的數據,那麼推薦將網頁源代碼使用lxml來解析,因爲lxml底層使用的是c餘言,所以解析效率會更高。
3. 如果想要對元素進行一些操作,比如給一個文本框輸入值,或者是點擊某個按鈕,那麼就必須使用selenium給我們提供的查找元素的方法

操作表單元素

常見的表單元素:

  • input : type=‘text | password |email | number | checkbox’
  • button : button | input[type=‘submit’]
  • select : 下拉選擇
  1. 操作輸入框:分爲兩步,第一步:找到這個元素;第二步:使用send_key(value)將數據填充進入。使用clear()方法可以清除輸入框中的內容。代碼如下:
    # 根據id獲取元素
    input_kw = driver.find_element_by_id('kw')
    # input表單
    input_kw.send_keys('python')
    # 清除輸入框中內容
    input_kw.clear()
    
  2. 操作checkbox:因爲要選中checkbox標籤,在網頁中是通過鼠標點擊的,因此想要選中checbox標籤,那麼先選中這個標籤,然後執行click()事件,代碼如下:
    # 根據name獲取元素
    rememberEle = driver.find_element_by_name('remember')
    rememberEle.click()
    
  3. 選擇select:select元素不能直接點擊,因爲點擊後還需要選中元素。這時候selenium就專門爲select標籤提供了一個類selenium.webdriver.soupport.ui.Select。將獲取到的元素當成參數傳到這個類中,創建對象。以後就可以使用這個對象進行選擇了,代碼如下:
    from selenium.webdriver.support.ui import Select
    
    # 根據name獲取元素
    select_tag = driver.find_element_by_name('jumpMenu')
    select_btn = Select(select_tag)
    # 根據索引進行選擇
    # select_btn.select_by_index(1)
    # 根據值進行選擇
    # select_btn.select_by_value('http://www.95you.com')
    # 根據可見文本進行選擇
    select_btn.select_by_visible_text('廣州東百信息科技有限公司')
    # 取消選中的所有選擇
    select_btn.deselect_all()
    # select_btn.deselect_by_index(1)
    # select_btn.select_by_value('http://www.95you.com')
    # select_btn.deselect_by_visible_text('廣州東百信息科技有限公司')
    
  4. 操作按鈕:操作按鈕有很多種方式,比如單擊、右擊、雙擊等。這裏將一個最簡單的,就是點擊,直接調用click()函數就可以了,代碼如下:
    # 操作按鈕
    input_btn = driver.find_element_by_id('reg_btn')
    input_btn.click()
    

示例代碼如下:

# 引入所需庫
import time

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

# 聲明定義chromedriver路徑
path = r'E:\Python_Code\s1\chromedriver_win32\chromedriver.exe'
# 實例化Chrome
# 如果時其他瀏覽器需要實例化爲對應的對象,例如火狐webdriver.firefox()
driver = webdriver.Chrome(path)
# 操作輸入框
# driver.get('https://www.baidu.com/')
# time.sleep(2)
# 根據id獲取元素
# input_kw = driver.find_element_by_id('kw')
# input表單
# input_kw.send_keys('python')

# 操作checkbox
# driver.get('https://www.douban.com/')
# time.sleep(2)
# # 根據name獲取元素
# rememberEle = driver.find_element_by_name('remember')
# rememberEle.click()

# 操作select
driver.get('http://95yueba.com/')
time.sleep(2)
# 根據name獲取元素
select_tag = driver.find_element_by_name('jumpMenu')
select_btn = Select(select_tag)
# 根據索引進行選擇
# select_btn.select_by_index(1)
# 根據值進行選擇
# select_btn.select_by_value('http://www.95you.com')
# 根據可見文本進行選擇
select_btn.select_by_visible_text('廣州東百信息科技有限公司')
# 取消選中的所有選擇
select_btn.deselect_all()
# select_btn.deselect_by_index(1)
# select_btn.select_by_value('http://www.95you.com')
# select_btn.deselect_by_visible_text('廣州東百信息科技有限公司')
time.sleep(2)

# 操作按鈕
input_btn = driver.find_element_by_id('reg_btn')
input_btn.click()

# 關閉當前頁面
driver.close()

獲取截屏

我們也可進行截取頁面形成圖片進行保存,示例代碼如下:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
# 聲明定義chromedriver路徑
path = r'E:\Python_Code\s1\chromedriver_win32\chromedriver.exe'
# 實例化Chrome
driver = webdriver.Chrome(executable_path=path, options=options)
driver.get('https://httpbin.org/ip')
# 進行截屏保存
driver.save_screenshot('1.png')

其他截屏方法:

  • get_screenshot_as_base64(): 獲取當前窗口的截圖保存爲一個base64編碼的字符串。
  • get_screenshot_as_file(filename): 獲取當前窗口的截圖保存爲一個png格式的圖片,filename參數爲圖片的保存地址,最後應該以.png結尾。如果出現IO錯誤,則返回False。用法: driver.get_screenshot_as_file('/Screenshots/foo.png')
  • get_screenshot_as_png(): 獲取當前窗口的截圖保存爲一個png格式的二進制字符串。

獲取窗口信息

  • get_window_position(windowHandle=’current’): 獲取當前窗口的x,y座標。
  • get_window_rect(): 獲取當前窗口的x,y座標和當前窗口的高度和寬度。
  • get_window_size(windowHandle=’current’): 獲取當前窗口的高度和寬度。

執行JS代碼

  1. execute_async_script(script, *args) : 在當前的window/frame中異步執行JS代碼。
    • script:是你要執行的JS代碼。
    • *args:是你的JS代碼執行要傳入的參數。
    • 用法:
    script = "var callback = arguments[arguments.length - 1]; "
    script2 = "window.setTimeout(function(){ callback('timeout') }, 3000);" 
    driver.execute_async_script(script + script2)
    
  2. execute_script(script, *args): 在當前的window/frame中同步執行JS代碼。
    • script:是你要執行的JS代碼。
    • *args:是你的JS代碼執行要傳入的參數。

其他博文鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章