柚子快報邀請碼778899分享:運維 爬蟲-瀏覽器自動化
柚子快報邀請碼778899分享:運維 爬蟲-瀏覽器自動化
什么是selenium
selenium是瀏覽器自動化測試框架,原本用于網(wǎng)頁測試。但到了爬蟲領(lǐng)域,它又成為了爬蟲的好幫手。有了?selenium,我們便不再需要判斷網(wǎng)頁數(shù)據(jù)加載的方式,只要讓?selenium?自動控制瀏覽器,就像有雙無形的手,控制著你的鼠標和鍵盤,自動地幫你干活。爬取數(shù)據(jù)?自動搶票?這些當(dāng)然統(tǒng)統(tǒng)都不在話下。
安裝selenium
和安裝python的第三方庫是一樣的
pip install selenium
selenium還需要安裝相應(yīng)的瀏覽器驅(qū)動才能控制瀏覽器。強烈推薦使用Chorme瀏覽器。
查看自己電腦上的瀏覽器版本,依次點擊瀏覽器右上角的?三個點?-?幫助?-?關(guān)于 Google Chrome。
將下載的對應(yīng)版本的的?chromedriver?解壓縮,Windows 系統(tǒng)得到?chromedriver.exe,這個就是我們需要的瀏覽器驅(qū)動。我們要將它放到 Python 所在安裝目錄里。
為了驗證驅(qū)動是否安裝成功,Windows 系統(tǒng)在的?命令行?或者?Anaconda Prompt?中輸入?chromedriver?命令,如果出現(xiàn)類似下圖所示的內(nèi)容,就證明驅(qū)動已經(jīng)安裝成功了。
打開瀏覽器
來看下如何用selenium打開Chrom瀏覽器
# 從 selenium 中導(dǎo)入 webdriver(驅(qū)動)
from selenium import webdriver
# 選擇 Chrome 瀏覽器并打開
browser = webdriver.Chrome()
獲取數(shù)據(jù)
# 從 selenium 中導(dǎo)入 webdriver(驅(qū)動)
from selenium import webdriver
# 選擇 Chrome 瀏覽器打開
browser = webdriver.Chrome()
# 打開網(wǎng)頁
browser.get('https://wpblog.x0y1.com')
# 關(guān)閉瀏覽器
browser.quit()
browser?是我們實例化的瀏覽器。我們將網(wǎng)址傳給?browser?對象的?get()?方法,即可打開對應(yīng)的網(wǎng)頁。最后調(diào)用?quit()?方法將瀏覽器關(guān)閉。
我們的目的是獲取數(shù)據(jù),接下來讓我們用?browser?對象的?page_source?屬性來獲取網(wǎng)頁的源代碼。值得注意的是,用?selenium?獲取的網(wǎng)頁源代碼是數(shù)據(jù)加載完畢后最終的源代碼,也就是網(wǎng)頁加載后通過 API 獲取的數(shù)據(jù)也在這個源代碼中。
因此,我們就不用再區(qū)分要爬取的網(wǎng)頁是靜態(tài)網(wǎng)頁還是動態(tài)網(wǎng)頁了,在?selenium?眼里統(tǒng)統(tǒng)都一樣。
代碼作用browser? =?webdriver.Chrome()打開Chrome瀏覽器browser.get("網(wǎng)址")打開網(wǎng)頁browser.page_source獲取網(wǎng)頁源代碼browser.quit()關(guān)閉瀏覽器
處理數(shù)據(jù)
我們來看看如何用?selenium?處理數(shù)據(jù)。我們以獲取博客的?h1?元素為例。
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://wpblog.x0y1.com')
h1 = browser.find_element(by='tag name', value='h1')
# 上面的代碼也可以寫成
# h1 = browser.find_element('tag name', 'h1')
print(h1.text)
browser.quit()
方法作用find_element(by = 'tag name', value=...)通過標簽查找元素find element(by = 'class name', value=...)?通過 class 屬性名查找元素find element(by = 'id', value=...)?通過 id 查找元素find element(by = 'name', value=...)通過 name 屬性查找元素find element(by = 'Link text', value=...)?通過鏈接文本查找元素find element(by = 'partial link text', value=...)?通過鏈接的部分文本查找元素
這些方法找到的元素(返回值)都是?WebElement?對象,它和?BeautifulSoup?里的?Tag?對象一樣,也有一個?text?屬性,一樣也是獲取元素里的文本內(nèi)容。
BeautifulSoup?中通過?select()?方法查找所有被所傳入的 CSS 選擇器選中的元素。剛才介紹的那些方法都是查找第一個符合條件的元素,接下來我們來看看?selenium?中查找所有符合條件的元素的方法。
這些方法非常簡單,直接把?find_element()?方法改成?find_elements()?方法即可:
方法作用find_elements(by = 'tag name', value=...)通過標簽查找元素find elements(by = 'class name', value=...)?通過 class 屬性名查找元素find elements(by = 'id', value=...)?通過 id 查找元素find elements(by = 'name', value=...)通過 name 屬性查找元素find elements(by = 'Link text', value=...)?通過鏈接文本查找元素find elements(by = 'partial link text', value=...)?通過鏈接的部分文本查找元素
?比如獲取網(wǎng)頁源代碼中所有的a元素
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://wpblog.x0y1.com')
# 注意下面是 elements
a_tags = browser.find_elements('tag name', 'a')
for tag in a_tags:
print(tag.text)
browser.quit()
值得一提的是,WebElement?對象也可以調(diào)用?selenium?查找元素的方法。這樣就和?BeautifulSoup?中的?Tag?對象一樣,可以一層一層的查找元素,直到找到為止。
BeautifulSoup?的原理是將網(wǎng)頁源代碼的字符串形式解析成?BeautifulSoup 對象,然后通過?BeautifulSoup 對象?的屬性和方法提取出我們需要的數(shù)據(jù)。發(fā)現(xiàn)沒有?BeautifulSoup?只需要一個網(wǎng)頁源代碼的字符串形式即可。
之前我們都是使用?requests?庫獲取網(wǎng)頁源代碼,并通過?text?屬性取得其字符串形式。而?selenium?獲取網(wǎng)頁后的?page_source?屬性值正是字符串格式的!
以上面獲取博客網(wǎng)頁源代碼中所有的?a 元素?為例,加上?BeautifulSoup?可以這樣寫:
from selenium import webdriver
from bs4 import BeautifulSoup
browser = webdriver.Chrome()
browser.get('https://wpblog.x0y1.com')
# 用 BeautifulSoup 解析網(wǎng)頁源代碼
soup = BeautifulSoup(browser.page_source, 'html.parser')
a_tags = soup.select('a')
for tag in a_tags:
print(tag.text)
browser.quit()
我寫了一個兩者結(jié)合爬取豆瓣讀書的代碼
import time
from selenium import webdriver
from bs4 import BeautifulSoup
browser = webdriver.Chrome()
browser.get("https://book.douban.com/top250/")
time.sleep(2)
#soup = BeautifulSoup(res.text, 'html.parser')
soup = BeautifulSoup(browser.page_source, 'html.parser')
#print(soup)
# 所有書名所在元素
book_name_tags = soup.select("a")
#print(book_name_tags)
book_names = []
for book_name in book_name_tags:
name = book_name.attrs
if 'title' in name:
book_names.append(name['title'])
# 所有書籍信息所在元素
book_info_tags = soup.find_all('p', class_="pl")
for i in range(len(book_names)):
name = book_names[i]
author = book_info_tags[i].text.split('/')[0]
publisher = book_info_tags[i].text.split('/')[-3]
print("%s / %s / %s" % (name, author, publisher))
browser.quit()
?返回的結(jié)果如下:
紅樓夢 / [清] 曹雪芹 著 ?/ ?人民文學(xué)出版社? 活著 / 余華 ?/ ?作家出版社? 1984 / [英] 喬治·奧威爾 ?/ ?北京十月文藝出版社? 哈利·波特 / J.K.羅琳 (J.K.Rowling) ?/ ?人民文學(xué)出版社? 三體全集 / 劉慈欣 ?/ ?重慶出版社? 百年孤獨 / [哥倫比亞] 加西亞·馬爾克斯 ?/ ?南海出版公司? 飄 / [美國] 瑪格麗特·米切爾 ?/ ?譯林出版社? 動物農(nóng)場 / [英] 喬治·奧威爾 ?/ ?上海譯文出版社? 三國演義(全二冊) / [明] 羅貫中 ?/ ?人民文學(xué)出版社? 房思琪的初戀樂園 / 林奕含 ?/ ?北京聯(lián)合出版公司? 福爾摩斯探案全集(上中下) / [英] 阿·柯南道爾 ?/ ?1981-8? 白夜行 / [日] 東野圭吾 ?/ ?南海出版公司? 小王子 / [法] 圣??颂K佩里 ?/ ?人民文學(xué)出版社? 安徒生童話故事集 / (丹麥)安徒生 ?/ ?人民文學(xué)出版社? 天龍八部 / 金庸 ?/ ?生活·讀書·新知三聯(lián)書店? 撒哈拉的故事 / 三毛 ?/ ?哈爾濱出版社? 吶喊 / 魯迅 ?/ ?人民文學(xué)出版社? 鄧小平時代 / 【美】傅高義 (Ezra.F.Vogel) ?/ ?生活·讀書·新知三聯(lián)書店? 悉達多 / [德] 赫爾曼·黑塞 ?/ ?天津人民出版社? 殺死一只知更鳥 / [美] 哈珀·李 ?/ ?譯林出版社? 明朝那些事兒(1-9) / 當(dāng)年明月 ?/ ?中國海關(guān)出版社? 失蹤的孩子 / [意] 埃萊娜·費蘭特 ?/ ?人民文學(xué)出版社? 新名字的故事 / [意] 埃萊娜·費蘭特 ?/ ?人民文學(xué)出版社? 野草 / 魯迅 ?/ ?人民文學(xué)出版社? 沉默的大多數(shù) / 王小波 ?/ ?中國青年出版社
?控制瀏覽器
我們要想登錄博客,那必須具備登錄的動作,再學(xué)習(xí)兩個方法,分別是:click() 和 send_keys()
方法作用click() 點擊元素 send_keys()模擬按鍵輸入
看下其在代碼中的應(yīng)用
from selenium import webdriver
import time
browser = webdriver.Chrome()
# 打開博客
browser.get('https://wpblog.x0y1.com')
# 找到登錄按鈕
login_btn = browser.find_element('link text', '登錄')
# 點擊登錄按鈕
login_btn.click()
# 等待 2 秒鐘,等頁面加載完畢
time.sleep(2)
# 找到用戶名輸入框
user_login = browser.find_element('id', 'user_login')
# 輸入用戶名
user_login.send_keys('codetime')
# 找到密碼輸入框
user_pass = browser.find_element('id', 'user_pass')
# 輸入密碼
user_pass.send_keys('shanbay520')
# 找到登錄按鈕
wp_submit = browser.find_element('id', 'wp-submit')
# 點擊登錄按鈕
wp_submit.click()
# 找到 Python 分類文章鏈接
python_cat = browser.find_element('css selector', 'section#categories-2 ul li a')
# 點擊該分類
python_cat.click()
# 找到跳轉(zhuǎn)的頁面中的所有文章標題元素
titles = browser.find_elements('css selector', 'h2.entry-title a')
# 找到標題元素中內(nèi)含的鏈接
links = [i.get_attribute('href') for i in titles]
# 依次打開 links 中的文章鏈接
for link in links:
browser.get(link)
# 獲取文章正文內(nèi)容
content = browser.find_element('class name', 'entry-content')
print(content.text)
browser.quit()
柚子快報邀請碼778899分享:運維 爬蟲-瀏覽器自動化
推薦閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。