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的功能!
自從Selenium
和PhantomJS
"分手"之後,使用Selenium
+Headless Chrome
成爲主流。
其他瀏覽器的driver
- Chrome : https://sites.google.com/a/chromium.org/chromedriver/downloads
- Firefox : https://github.com/mozilla/geckodriver/releases
- Edge : https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
- Safari : https://webkit.org/blog/6900/webdriver-support-in-safari-10/
安裝Selenium+chromedriver
- 安裝
Selenium
:Selenium
有很多語言的版本,有java、ruby、python等。我們使用pip
安裝python版本即可:
$ pip install selenium
- 安裝
chromedriver
:下載相應的chromedriver
放到不需要權限的純英文目錄下就可以了。版本號對應描述:http://chromedriver.storage.googleapis.com/2.40/notes.txt
簡單使用
獲取百度首頁
現在我們以一個簡單的獲取百度首頁的例子來講下Selenium
和chromedriver
如何快速入門,示例代碼如下:
# 引入所需庫
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/
關閉頁面
driver.close()
: 關閉當前頁面。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()
定位元素
find_element_by_id
: 根據id來查找某個元素。等價於:input_kw = driver.find_element_by_id('kw') input_kw = driver.find_element(By.ID, 'kw')
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')
find_element_by_name
: 根據name屬性的值來查找元素,等價於:input_kw = driver.find_element_by_name('wd') input_kw = driver.find_element(By.ID, 'wd')
find_element_by_tag_name
: 根據標籤名來查找元素,等價於:input_kw = driver.find_element_by_tag_name('input') input_kw = driver.find_element(By.TAG_NAME, 'input')
find_element_by_xpath
: 根據xpath語法來獲取元素,等價於:
使用selenium中xpath獲取元素屬性值得時候和真實的xpath語法有些不同,例如獲取a標籤的href屬性值,在真實的xpath語法中使用input_kw = driver.find_element_by_xpath('//input[@id="kw"]') input_kw = driver.find_element(By.XPATH, '//input[@id="kw"]')
//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")
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
: 下拉選擇
- 操作輸入框:分爲兩步,第一步:找到這個元素;第二步:使用
send_key(value)
將數據填充進入。使用clear()
方法可以清除輸入框中的內容。代碼如下:# 根據id獲取元素 input_kw = driver.find_element_by_id('kw') # input表單 input_kw.send_keys('python') # 清除輸入框中內容 input_kw.clear()
- 操作checkbox:因爲要選中
checkbox
標籤,在網頁中是通過鼠標點擊的,因此想要選中checbox
標籤,那麼先選中這個標籤,然後執行click()
事件,代碼如下:# 根據name獲取元素 rememberEle = driver.find_element_by_name('remember') rememberEle.click()
- 選擇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('廣州東百信息科技有限公司')
- 操作按鈕:操作按鈕有很多種方式,比如單擊、右擊、雙擊等。這裏將一個最簡單的,就是點擊,直接調用
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代碼
- 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)
- execute_script(script, *args): 在當前的window/frame中同步執行JS代碼。
- script:是你要執行的JS代碼。
- *args:是你的JS代碼執行要傳入的參數。
其他博文鏈接
- Python爬蟲1.1 — urllib基礎用法教程
- Python爬蟲1.2 — urllib高級用法教程
- Python爬蟲1.3 — requests基礎用法教程
- Python爬蟲1.4 — requests高級用法教程
- Python爬蟲2.1 — BeautifulSoup用法教程
- Python爬蟲2.2 — xpath用法教程
- Python爬蟲3.1 — json用法教程
- Python爬蟲3.2 — csv用法教程
- Python爬蟲3.3 — txt用法教程
- Python爬蟲4.1 — threading(多線程)用法教程
- Python爬蟲4.2 — ajax(動態網頁數據抓取)用法教程