有些時候我們需要用到百度文庫的某些文章時,卻發現需要會員才能下載,很難受,其實我們可以通過爬蟲的方式來獲取到我們所需要的文本。
工具:python3.7+selenium+任意一款編輯器
前期準備:可以正常使用的瀏覽器,這裏推薦chrome,一個與瀏覽器同版本的驅動,這裏提供一個下載驅動的鏈接https://chromedriver.storage.googleapis.com/77.0.3865.40/chromedriver_win32.zip
首先我們來看一下百度文庫中這一篇文章https://wenku.baidu.com/view/5b1ef2cfbf23482fb4daa58da0116c175e0e1e0a.html
可以看到,在文章的最末尾需要我們來點擊繼續閱讀才能爬取到所有的文字,不然我們只能獲取到一部分的文字。這給我們的爬蟲帶來了一些困擾。因此,我們需要藉助selenium這一個自動化工具來幫助我們的程序完成這一操作。
from selenium import webdriver from selenium.webdriver.common.keys import Keys import time from bs4 import BeautifulSoup import re driver = webdriver.Chrome('D:/chromedriver.exe') driver.get("https://wenku.baidu.com/view/5b1ef2cfbf23482fb4daa58da0116c175e0e1e0a.html")
我們先通過驅動器來請求這個頁面,
可以看到,已經請求成功這個頁面了。接下來需要我們通過驅動來點擊繼續閱讀來加載到這篇文章的所有文字。我們通過f12審查元素,看看
然後通過selenium的定位功能,定位到左邊黃色區域所在的位置,調用驅動器進行點擊
driver = webdriver.Chrome('D:/chromedriver.exe') driver.get("https://wenku.baidu.com/view/5b1ef2cfbf23482fb4daa58da0116c175e0e1e0a.html") driver.find_element_by_xpath("//*[@id='html-reader-go-more']/div[2]/div[1]/p").click()
然後執行看看
黃字是報錯的信息,顯示的是有另外一個元素接受了點擊的調用。可能是屏幕沒有滑動到下方,直接點擊被遮蓋了。所以我們要通過驅動器先將瀏覽器滑動到底部,再點擊繼續閱讀
from selenium import webdriver from selenium.webdriver.common.keys import Keys import time from bs4 import BeautifulSoup import re driver = webdriver.Chrome('D:/chromedriver.exe') driver.get("https://wenku.baidu.com/view/5b1ef2cfbf23482fb4daa58da0116c175e0e1e0a.html") page=driver.find_element_by_xpath("//*[@id='html-reader-go-more']/div[2]/div[1]/p") driver.execute_script('arguments[0].scrollIntoView();', page) #拖動到可見的元素去 page=driver.find_element_by_xpath("//*[@id='html-reader-go-more']/div[2]/div[1]/p").click()
先獲取到繼續閱讀所在頁面的位置,然後使用
driver.execute_script('arguments[0].scrollIntoView();', page) #拖動到可見的元素去方法將頁面滾動到可以點擊的位置
這樣就獲取到了整個完整頁面,在使用beautifulsoup進行解析
html=driver.page_source bf1 = BeautifulSoup(html, 'lxml') result=bf1.find_all(class_='page-count') num=BeautifulSoup(str(result),'lxml').span.string count=eval(repr(num).replace('/', '')) page_count=int(count) for i in range(1,page_count+1): result=bf1.find_all(id="pageNo-%d"%(i)) for each_result in result: bf2 = BeautifulSoup(str(each_result), 'lxml') texts = bf2.find_all('p') for each_text in texts: main_body = BeautifulSoup(str(each_text), 'lxml') s=main_body.get_text()
最後在寫入txt文檔
f=open("baiduwenku.txt","a",encoding="utf-8") f.write(s) f.flush() f.close()