Python3爬虫-selenium爬取百度文库
? ? ? 這是筆者爬取的第一個動態(tài)加載的網(wǎng)頁,使用的IDE是Pycharm,選擇的是百度文庫的一篇16年六級卷子的文檔。若直接使用requests模塊去得到網(wǎng)頁源碼,會發(fā)現(xiàn)所得非所見,不能獲取到文檔中的內(nèi)容。看了網(wǎng)上數(shù)篇博文的思路,最后還是嘗試了使用selenium模塊模擬安卓設(shè)備使用chrome瀏覽器訪問,這樣訪問可以獲得網(wǎng)頁的完整源碼。這篇文檔默認加載了不到20%,點擊“繼續(xù)閱讀”字樣,之后內(nèi)容加載到20%,這時若想要內(nèi)容需要點擊的字樣變成了“點擊加載更多”,連續(xù)點擊“點擊加載更多”直到所有文檔內(nèi)容都已加載,此時再使用selenium的page_source方法獲取完整的網(wǎng)頁源碼,得到源碼后的操作就輕松了很多,使用BeautifulSoup模塊從源碼中獲取需要的文檔內(nèi)容,之后用python-docx模塊將獲取的文檔內(nèi)容存到本地文檔中。雖然代碼不長,但還是踩到了不少坑,先放代碼吧,然后再填坑。
?
#!/usr/bin/env python3 # -*- coding: utf-8 -*-import lxml from bs4 import BeautifulSoup import time import docx import re from selenium.webdriver.common.action_chains import ActionChains from selenium import webdriver#模擬移動設(shè)備使用chrome打開指定頁面 options = webdriver.ChromeOptions() options.add_argument('user-agent="Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19"') driver = webdriver.Chrome(r"C:\Users\hhp\AppData\Local\Google\Chrome\Application\chromedriver.exe",chrome_options=options) driver.get('https://wenku.baidu.com/view/83dd3c6f6bec0975f565e29f.html')#模擬鼠標點擊“繼續(xù)閱讀” time.sleep(2) pos = driver.find_element_by_xpath("//div[@class='foldpagewg-root']") ActionChains(driver).move_to_element(pos).click(pos).perform()#模擬鼠標點擊“點擊加載更多“ pos2 = driver.find_element_by_xpath("//div[@class='btns-warp']") pos3 = driver.find_element_by_xpath("//div[@class='pagerwg-button']")loop = 1 while loop <= 5:time.sleep(1)ActionChains(driver).move_to_element(pos2).perform()ActionChains(driver).click(pos3).perform()loop = loop + 1#從得到的完整頁面源碼提取數(shù)據(jù)并存儲 html = driver.page_source bf = BeautifulSoup(html,'lxml') get_docx_name = bf.find(class_='doc-title').get_text() docx_name = re.sub('\s','',get_docx_name)+'.docx' pages = bf.find_all(class_='content singlePage wk-container')file = docx.Document() with open('2016-6-I-six.txt', 'w',encoding = 'utf-8') as f:for page in pages:para = page.find_all(class_ = 'txt')for p in para:text = p.get_text()f.write(text+'\n')file.add_paragraph(text) file.save(docx_name)?
使用到的模塊
BeautifulSoup模塊用來從html中提取數(shù)據(jù),這里使用lxml HTML解析器,引入了lxml模塊
time模塊在代碼中使用到延時函數(shù),這里就是為了暫緩一下程序的執(zhí)行,能更清楚的看到chrome瀏覽器被調(diào)用后整個操作流程,可有可無
re模塊用到了sub函數(shù)處理字符串
docx模塊踩到了連環(huán)坑,安裝python-docx模塊就好了
selenium模塊用來操縱chrome瀏覽器,當然其功能不止于chrome
?
驅(qū)動問題
使用selenium操縱chrome瀏覽器先確定要有chromedriver驅(qū)動,沒有的話會報錯,可以從
http://npm.taobao.org/mirrors/chromedriver/下載驅(qū)動
下載時要注意自己瀏覽器的版本,驅(qū)動與瀏覽器版本對應(yīng)關(guān)系可以在http://npm.taobao.org/mirrors/chromedriver/2.40/notes.txt中找到,截圖如下。
??如果不清楚自己瀏覽器的版本,可以在chrome地址欄中輸入 chrome://version
打開的界面如圖,筆者的chrome是v67,沒有更新到最新版,下載驅(qū)動要看好版本間對應(yīng)關(guān)系
?
下載好的chromedriver.exe驅(qū)動要放置到自己安裝的chrome瀏覽器的安裝目錄下,筆者驅(qū)動的路徑是
C:\Users\hhp\AppData\Local\Google\Chrome\Application\chromedriver.exe
設(shè)置環(huán)境變量:
通過 我的電腦-屬性-高級系統(tǒng)設(shè)置-高級-環(huán)境變量-Path? 添加chromedriver.exe所在位置
?
具體代碼
- 打開網(wǎng)頁
?
options = webdriver.ChromeOptions()
設(shè)置啟動chrome時的選項,這里的用途是設(shè)置user-agent選項模擬移動設(shè)備
這兩句會打開chrome瀏覽器并打開指定的那篇文檔的頁面
筆者這里webdriver.chrome()的寫法是沒有配置chromedriver的環(huán)境變量,其中加的r是為了規(guī)避反斜杠的轉(zhuǎn)義
如果配置過環(huán)境變量,可以寫成
webdriver.Chrome(chrome_options=options)
如果你在設(shè)置環(huán)境變量時IDE是正在運行的,需要重啟IDE后設(shè)置的環(huán)境變量才生效,否則直接運行程序會報錯:
selenium.common.exceptions.WebDriverException: Message: 'ChromeDriver executable needs to be available in the path.
?
?
- 模擬鼠標獲取完整網(wǎng)頁
如上圖,通過xpath的相對定位方式選擇具有'foldpagewg-root'樣式的div標簽,在此div應(yīng)用到的區(qū)域內(nèi),點擊鼠標均可加載更多,如圖左半部分陰影所示。關(guān)于xpath方法查找元素,筆者水平很有限,還不能作很好的總結(jié),大家可以查閱網(wǎng)上的詳細講解。
這里只用到了相對定位,即'//'開頭,與之對應(yīng)便有絕對定位。可以看如下例子
如果要定位到圈中的位置,絕對定位以'/'表示,且從根節(jié)點開始,寫法是/html/body/div[@id='BAIDU_DUP_fp_wrapper']
相對定位更為簡短 //div[@id='BAIDU_DUP_fp_wrapper']
?
ActionChains(driver).move_to_element(pos).click(pos).perform()是模擬鼠標操作,之后可以看到文檔加載到20%
其中的move_to_element()將鼠標移動到之前定位的pos位置,click()函數(shù)模擬鼠標左鍵單擊,perform()將操作執(zhí)行
?
?
pos2 = driver.find_element_by_xpath("//div[@class='btns-warp']") pos3 = driver.find_element_by_xpath("//div[@class='pagerwg-button']")loop = 1 while loop <= 5:time.sleep(1)ActionChains(driver).move_to_element(pos2).perform()ActionChains(driver).click(pos3).perform()loop = loop + 1?
在內(nèi)容加載到20%之后,想要加載更多需要點擊“點擊加載更多”,上面的pos2,pos3的定位就是為此
這里也遇到了小問題,一開始move_to_element()是直接移動到pagerw-button位置,之后的click()也是點擊這里,但代碼執(zhí)行起來并沒有加載更多,觀察chrome的操作過程發(fā)現(xiàn),這樣的鼠標移動方式并沒有將頁面下拉到足以顯示出“點擊加載更多”字樣,也就是說其被遮擋了,click()點擊操作錯誤地指向網(wǎng)頁的其他元素。move_to_element的效果類似于用鼠標滾輪下滑網(wǎng)頁,把網(wǎng)頁滑動到一個指定的位置便停止,修改代碼為鼠標移動到div class='btns-warp'位置后,這時的網(wǎng)頁中點擊加載更多不再被遮擋,再用click()執(zhí)行點擊可以正常完成。這里循環(huán)五次是為了使網(wǎng)頁內(nèi)容全部加載完畢。
?
- 從獲得的完整網(wǎng)頁提取數(shù)據(jù)
?
經(jīng)過上述模擬鼠標點擊操作獲得完整網(wǎng)頁源碼后,剩下的操作就更為簡單,page_source獲得網(wǎng)頁源碼,然后使用BeautifulSoup模塊從html源碼中提取數(shù)據(jù)。
get_docx_name = bf.find(class_='doc-title').get_text()這句是為了獲得文檔名,使用BeautifulSoup的find方法找到包含文檔名的div標簽
?
docx_name = re.sub('\s','',get_docx_name)+'.docx'sub()將get_docx_name字符串中的所有不可顯字符替換為 '',效果就是去除了這些不可顯字符,如空格,換行符
?
pages = bf.find_all(class_='content singlePage wk-container')這句從網(wǎng)頁代碼中選取包含文檔每一頁的部分
?
file = docx.Document() with open('2016-6-I-six.txt', 'w',encoding = 'utf-8') as f:for page in pages:para = page.find_all(class_ = 'txt')for p in para:text = p.get_text()f.write(text+'\n')file.add_paragraph(text) file.save(docx_name)最后這部分代碼提取文本的文字內(nèi)容,存儲到本地,這里同時存儲為了docx和txt文件,這里用到的文件操作較為簡單,很容易上手。
f.write(text+'\n')中的+'\n'是為了換行,否則存為的txt文件很亂。而docx模塊還有很多很多功能,這里也只是用到了最為基礎(chǔ)的插入文本。
page.find_all(class_='txt')是獲取到每頁中的所有段落,下圖有對應(yīng)關(guān)系,函數(shù)返回值類型是列表
所以有了之后的for p in pages循環(huán),p.get_text()提取到真正的文本
file.save()保存文件,路徑可以自己指定,這里只寫了一個docx_name,會保存到默認路徑,即和這份代碼同一路徑,例如筆者這份代碼test.py路徑為G:\Pycharm\test.py 文件默認會保存到G:\Pycharm,也可以自己指定,比如file.save('C:test_docx.docx')
程序執(zhí)行后得:
總結(jié)
? ? ? ??這是我的第一篇博客,第一篇的內(nèi)容選擇了python爬蟲,自己水平很有限,寫起來還是挺有壓力的。這里爬取的方法也只是設(shè)法獲得包含有文檔文本內(nèi)容的html源代碼,從中提取出文檔內(nèi)容后自己再生成文件,不過如果充分利用docx模塊可以對得到的數(shù)據(jù)進行自由排布。網(wǎng)上很多爬蟲文章的代碼都失效了,這篇文章權(quán)當提供一份可以實際操作的代碼去嘗試。當然隨著時間流逝,這份代碼也會失效,如果以后有了好的思路,筆者會對這篇文章做些增刪查改,或者推倒重來。最后添上一些文檔或者博客的鏈接。
?
?
參考的文章:
Selenium 之訂制啟動Chrome的選項(Options)
Beautiful Soup 4.4.0 文檔
Selenium-Python中文文檔
python-docx
Selenium之Action Chains類
Python3網(wǎng)絡(luò)爬蟲(九):使用Selenium爬取百度文庫word文章
?
總結(jié)
以上是生活随笔為你收集整理的Python3爬虫-selenium爬取百度文库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 堆积木——GBQ4.0设置“统一设置安装
- 下一篇: 4行代码 超级简单 html/css 实