前言:
爬取百度文库对于我这个刚入门的新手来说还是挺有挑战性的,前后历时三个晚上,终于给搞定了,成就感满满。
对于这种动态网站的的爬取,主要就是摸清规则,下面我就来说说的百度文库的规则,这也是我测试了好多遍才搞清。
刚打开网页时,会先加载前几页的文档,点击继续阅读后,不会加载余下的网页,需要你把滚动条下滚到那一页才会加载文档,但当你定位到已经加载的那一页文档时,前面几页的文档又会隐藏。
规则摸清了,接下来就是制定方案了。
方案:一页一页的爬取,先爬第一页,再第二页---依次类推,遇到没有加载的就让他加载(如果需要翻页就翻页,需要下滚就下滚)。
实战:
1-1:
对于Selenium和BeautifulSoup我就不多介绍,网上有很多教程,只说几个本章要用的:
1.Selenium:
①:ActionChains: 模拟用户和浏览器的交互,比如鼠标点击,键盘输入等
②:webdrive
2.BeautifulSoup
1-2:
代码如下:
要爬取的网页:https://wenku.baidu.com/view/aa31a84bcf84b9d528ea7a2c.html
from selenium import webdriver
from bs4 import BeautifulSoup
from selenium.webdriver import ActionChains
import time
options = webdriver.ChromeOptions()
options.add_argument('user-agent="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"')
driver = webdriver.Chrome(chrome_options = options)
driver.get('https://wenku.baidu.com/view/aa31a84bcf84b9d528ea7a2c.html')
#获取总页数
html = driver.page_source
page_count_get = BeautifulSoup(html,'lxml')
page_count_gets = page_count_get.find(class_='page-count')
pagecount = page_count_gets.get_text()
num = int(pagecount[1:])
temp = num
page1 = 1 #从第一页开始爬取
#获取结果
while page1<=temp:
x='pageNo-'+str(page1) #当前页面元素
print(x)
html = driver.page_source
soup = BeautifulSoup(html,'lxml') #载入html
soups = soup.find_all(id = x) #找到所有id为x的元素
for each in soups:
text = each.get_text() #获取元素里的文字
print(text)
if num>1 and text == '': #如果页数大于1并且获取不到文章,就点击继续阅读
#模拟鼠标点击 ActionChain()方法
page = driver.find_element_by_css_selector("#html-reader-go-more")
pagebutton = driver.find_element_by_css_selector("#html-reader-go-more .banner-more-btn") #继续阅读按钮的元素位置
ActionChains(driver).move_to_element(page).click(pagebutton).perform() #执行鼠标单击行为
time.sleep(2)
num = num/5
page1 = page1-1
elif num<1 and text == '': #如果页数小于1(这里指的是不需要再点击继续阅读)并且获取不到文章,就下滚
target = driver.find_element_by_id(x) #找到id为x的元素,并定位,也就是当前正在爬取的页数
driver.execute_script("arguments[0].scrollIntoView();",target) #模拟滚动到id为x的地方,也就是当前正在爬取的页数
time.sleep(2)
page1 = page1-1
page1 = page1+1
运行结果:
欢迎大家在留言板讨论,欢迎指正错误。