Selenium庫的基本使用
selenium庫是用來爬取動態網頁的一個工具。什么是動態網頁?凡是能交互的網頁,都是動態網頁。比如有搜索框,能發表評論,能點贊,拉黑等等,因此現在很大部分網站都是動態網頁。它與靜態網頁不同的是,它不需要修改網頁源碼,就可以改變網頁展示的內容。它只需要修改服務器的數據庫等它關聯的數據即可。
一、什么是selenium庫?
Selenium是一個用於Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),[Mozilla Firefox](https://baike.baidu.com/item/Mozilla Firefox/3504923),Safari,Google Chrome,Opera,Edge等。這個工具的主要功能包括:測試與瀏覽器的兼容性——測試應用程序看是否能夠很好得工作在不同瀏覽器和操作系統之上。測試系統功能——創建回歸測試檢驗軟件功能和用戶需求。支持自動錄制動作和自動生成.Net、Java、Perl等不同語言的測試腳本。
總的來說,selenium庫就是用來模擬瀏覽器操作的。比如我們日常看視頻,需要先打開瀏覽器,輸入網址,在搜索框輸入關鍵字,然后回車,進入到新網頁,再點擊想要看的視頻。如果想查資料,操作基本上也差不多。
因此,想要用selenium庫寫爬蟲,需要先量化對瀏覽器的使用,要將打開瀏覽器,找到輸入框,打字,搜索,點擊新網頁等等這些操作看做一個個小模塊。分別掌握這些小模塊的語法操作。最后將這些步驟按順序放在一起就可以完成了。
二、准備工作
1、安裝Selenium庫(兩種方法)
①在Pycharm中用鼠標操作
②在命令提示符窗口安裝
2、准備瀏覽器和瀏覽器插件
推薦用谷歌和火狐。我使用的是谷歌瀏覽器
然后,打開這個chromedriver插件的下載網址
https://chromedriver.chromium.org/downloads
由於我的谷歌瀏覽器版本是92.0.4515版本,所以我下載如圖所示的這個版本的插件
下載后解壓,里面只有一個文件chromedriver.exe,將它放入python的安裝目錄下,即和python.exe文件一個目錄下即可。
如果你裝了Anaconda,還要將這個插件放到Anaconda自帶的python文件夾下,位置同上
三、基本操作
1、一個簡單的例子
# 打開清華大學出版社官網,搜索關鍵字python,將首頁的書本名和價格提取出來,並形成一個表格
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import pandas as pd
driver = webdriver.Chrome() # 生成一個瀏覽器對象
url = "http://www.tup.tsinghua.edu.cn/index.html" # 設置url
driver.get(url) # 將url傳給driver對象
input_tag = driver.find_element(By.CSS_SELECTOR, '#input_key') # 使用selector來定位輸入框
input_tag.send_keys("python") # 往輸入框中傳遞值
input_tag.send_keys(Keys.ENTER) # 模擬鍵盤的回車鍵
windows = driver.window_handles # 將目前已經打開的兩個網頁地址保存在windows列表中
driver.switch_to.window(windows[1]) # 將driver關聯的網頁切換到剛剛新打開的頁面
html = driver.page_source # 獲取driver當前頁面的網頁源碼,存儲在html變量中
soup = BeautifulSoup(html, 'lxml') # 新建一個BeautifulSoup對象,以lxml的形式解析html源碼,並存到soup變量中
book_name = [i.text for i in soup.select('#csproduct a span')] # 從soup中提取書名
editor = [i.text for i in soup.select('#csproduct a p')[::3]] # 從soup中提取作者姓名
p = [i.text for i in soup.select('#csproduct a p')[2::3]] # 從soup中提取書本價格
price = [] # 書本價格列表
for i in p: # 對於每一個在i,i的格式都形如“價格:83”,“價格:90“。為了后面方便生成表格,要去除數字以外的字符
i = i.replace('定價:', '') # 將每個元素中的‘定價:’刪除
price.append(i) # 將每一個修改過的i,加入提前准備的price列表中
table = pd.DataFrame({'書名': book_name, '價格': price}) # 生成兩列的表格,列名為書名和價格
print(table)
2、selenium庫的基礎操作
①選擇瀏覽器類型
from selenium import webdriver
# 選擇什么類型的瀏覽器,就在webdriver的方法中找對應的瀏覽器就行,這里就舉兩個例子,一個火狐一個谷歌
a = webdriver.Chrome()
b = webdriver.Firefox()
......
首字母大寫!是Chrome,不是chrome,小寫會報錯!
②給瀏覽器傳遞url
這里簡單說一下url和我們日常說的網址有什么區別?
(https://zhidao.baidu.com/question/1452275666155100260.html)
網址:我們日常輸入的,形如“www.baidu.com”,"www.4399.com"這樣的就是網址
url:url由三部分組成。協議,ip地址,資源地址。和網址相比,主要就是多了協議一欄。即類似"http://","https://"這樣的協議。
因此可以這么認為,開頭有協議的就是url,沒有協議的就是網址。
from selenium import webdriver
# 第一種方法
a = webdriver.Chrome()
a.get("https://www.baidu.com/")
# 第二種方法
url="https://www.baidu.com/"
a.get(url)
# 執行過后,瀏覽器就會自動跳轉到輸入的頁面
③定位輸入框並傳值
selenium一共有8種定位方法
定位方法 | 個體形式 | 復數形式 |
---|---|---|
id定位 | driver.find_element(By.ID, 'xxx') | driver.find_elements(By.ID, 'xxx') |
name定位 | driver.find_element(By.NAME, 'xxx') | driver.find_elements(By.NAME, 'xxx') |
class定位 | driver.find_element(By.CLASS_NAME, 'xxx') | driver.find_element(By.CLASS_NAME, 'xxx') |
tag定位 | driver.find_element(By.TAG_NAME, 'xxx') | driver.find_elements(By.TAG_NAME, 'xxx') |
link定位 | driver.find_element(By.LINK_TEXT, 'xxx') | driver.find_element(By.LINK_TEXT, 'xxx') |
partial_link定位 | driver.find_element(By.PARTIAL_LINK_TEXT, 'xxx') | driver.find_elements(By.PARTIAL_LINK_TEXT, 'xxx') |
xpath定位 | driver.find_element(By.XPATH, 'xxx') | driver.find_element(By.XPATH, 'xxx') |
css定位 | driver.find_element(By.CSS_SELECTOR, 'xxx') | driver.find_elements(By.CSS_SELECTOR, 'xxx') |
在這里我簡單介紹一下XPATH的語法。
XPATH
//全局選取,選子孫節點
/選取子節點
例如:
//div[@class='xxxxx']
//table[contains(@id,'xxxxxx')]
//*[@id='xxxx']
語法格式:
//節點名[@屬性名='屬性值']
//屬性名[contains(@屬性名,'屬性值')]
//*[@name='xxxx']
在網頁中按F12,檢查源碼,左鍵點擊快捷查找圖標,再點擊搜索框,即可定位到源碼中的具體位置
# 將這些方法導入
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome() # 生成一個瀏覽器對象
url = "http://www.tup.tsinghua.edu.cn/index.html" # 設置url
driver.get(url) # 將url傳給driver對象
input_tag = driver.find_element(By.CSS_SELECTOR, '#input_key') # 使用selector來定位輸入框
input_tag.send_keys("python") # 往輸入框中傳遞值
# 傳值這一步代碼執行后,我們會看到搜索框中多了python字眼
④點擊網頁元素
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome() # 生成一個瀏覽器對象
url = "http://www.tup.tsinghua.edu.cn/index.html" # 設置url
driver.get(url) # 將url傳給driver對象
input_tag = driver.find_element(By.CSS_SELECTOR, '#input_key') # 使用selector來定位輸入框
input_tag.send_keys("python") # 往輸入框中傳遞值
# 下面提供兩種傳值后進入新網頁的操作
# 1、模擬鍵盤的回車鍵
input_tag.send_keys(Keys.ENTER)
# 2、定位搜索標簽,並點擊,這里以通過XPATH定位為例
button = driver.find_element(By.XPATH, '/html/body/div[1]/div[1]/div[2]/div[2]/div[4]')
button.click()
⑤切換當前關聯的網址
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome() # 生成一個瀏覽器對象
url = "http://www.tup.tsinghua.edu.cn/index.html" # 設置url
driver.get(url) # 將url傳給driver對象
input_tag = driver.find_element(By.CSS_SELECTOR, '#input_key') # 使用selector來定位輸入框
input_tag.send_keys("python") # 往輸入框中傳遞值
input_tag.send_keys(Keys.ENTER) # 模擬鍵盤的回車鍵
windows = driver.window_handles # 將目前已經打開的兩個網頁地址保存在windows列表中
print("當前頁面:" + driver.current_window_handle + "\n")
print("現在一共有這些頁面:")
print(windows)
driver.switch_to.window(windows[1]) # 將driver關聯的網頁切換到剛剛新打開的頁面
print("\n切換后,現在的頁面:" + driver.current_window_handle)
'''
由於windows是一個列表,因此所有列表操作對windows也適用
比如
打開了很多網頁,想直接切換到最后一個,可以用windows[-1]來索引,同理[-2]是倒數第二個,[-3]是倒數第三個
'''
切換網址這個操作,就像C語言中改變指針類似,我一開始控制的是第一個網址,切換后我就可以控制新的網址了。
⑥提取目標網址的目標信息
# 導入BeautifulSoup庫
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
driver = webdriver.Chrome() # 生成一個瀏覽器對象
url = "http://www.tup.tsinghua.edu.cn/index.html" # 設置url
driver.get(url) # 將url傳給driver對象
input_tag = driver.find_element(By.CSS_SELECTOR, '#input_key') # 使用selector來定位輸入框
input_tag.send_keys("python") # 往輸入框中傳遞值
input_tag.send_keys(Keys.ENTER) # 模擬鍵盤的回車鍵
windows = driver.window_handles # 將目前已經打開的兩個網頁地址保存在windows列表中
driver.switch_to.window(windows[1]) # 將driver關聯的網頁切換到剛剛新打開的頁面
html = driver.page_source # 獲取driver當前頁面的網頁源碼,存儲在html變量中
soup = BeautifulSoup(html, 'lxml') # 新建一個BeautifulSoup對象,以lxml的形式解析html源碼,並存到soup變量中
book_name = [i.text for i in soup.select('#csproduct a span')] # 從soup中提取書名
editor = [i.text for i in soup.select('#csproduct a p')[::3]] # 從soup中提取作者姓名
p = [i.text for i in soup.select('#csproduct a p')[2::3]] # 從soup中提取書本價格
price = [] # 書本價格列表
for i in p: # 對於每一個在i,i的格式都形如“價格:83”,“價格:90“。為了后面方便生成表格,要去除數字以外的字符
i = i.replace('定價:', '') # 將每個元素中的‘定價:’刪除
price.append(i) # 將每一個修改過的i,加入提前准備的price列表中
print(str(book_name) + '\n')
print(str(editor) + '\n')
print(str(price))
⑦數據處理
四、總結
selenium庫的基本操作,是有一定的操作難度的,主要集中在如何准確定位網頁元素,如何獲取網頁源碼並提取出有效數據兩方面
但其實這兩方面,在靜態網頁爬取中也是核心步驟,因此兩者的知識是共通的,不需要學兩遍。本教程只是很簡單的舉了一個例子,還有很多工具沒有介紹到,因為我自己也沒學這么多,不方便講。剩下的就看各位自己去深造了。