中國知網爬蟲
一、知網介紹
提起中國知網,如果你曾經寫過論文,那麼基本上都會與中國知網打交道,因爲寫一篇論文必然面臨着各種查重,當然翟博士除外。但是,本次重點不在於寫論文跟查重上,而在於我們要爬取知網上一些論文的數據,什麼樣的數據呢?我們舉一個例子來說,在知網上,搜索論文的方式有很多種,但是對於專業人士來說,一般都會使用高級檢索,因爲直接去查找作者的話,容易查找到很多重名作者,所以我們本次的爬蟲也是使用了高級檢索(泛稱)的爬蟲,再具體就是專業檢索,有助於我們唯一定位到作者。
二、常規步驟—頁面分析
1.來到高級檢索頁面,以【AU=王長峯 AND FU=71271031】爲例檢索,結果如下:
2.利用Xpath語法嘗試獲取這些數據,卻發現一無所獲。
3.按照常理來說,即使是動態網頁也可以利用Xpath語法提取到數據,只是在Python裏面獲取不到而已,所以在這裏存在我們所不知道的問題。
三、知網反爬蟲機制
常見的反爬蟲機制一般有兩種:
第一種是請求頭反爬蟲,這個也是最簡單的,如果你不給定請求頭,對方服務器就不會理你。需要設置的參數有User-Agent、Referer和Cookie。
第二種是動態網頁,利用Ajax技術使用js接口來傳遞數據。
毫無疑問,對於數據非常金貴的中國知網來說,肯定使用了以上兩種反爬方式,並且中國知網的js接口非常複雜,雖說複雜,但是隻要你的內功要是足夠強的話,還是能夠分析得出來,但是對於不懂js以及web開發的朋友來說,這將是一個非常困難的事情,所以使用selenium來進行爬蟲將是一件相對來說比較容易的事情。
另外,知網也不是僅僅只有這兩層反爬蟲機制,還有第三層,那就是iframe,由於很多朋友並沒有做過網站開發,所以不太清楚了這是什麼東西,導致即使發現自己的Xpath語法正確,也無法正確獲取數據,從而懷疑人生,實際上,iframe比較常見的一種反爬蟲機制,不過,如果你不知道這個東西,那麼你就基本上無緣爬取中國知網了。
四、什麼是iframe?
瞭解iframe前,你首先得知道一個網頁是什麼,沒錯,一個網頁就是一個html頁面。接下來我們從感性和源碼兩個方面來認識一下iframe.
1.感性認知。
一句話:一個完整的網頁內部又嵌套了多個完整的網頁,嵌套的頁面就叫做iframe。
2.網頁源碼認識。
比如一個非常簡單的html頁面(如下圖所示),一個html頁面是擁有一個完整的html標籤的,也就是起始html【<html>】和閉合html【</html>】,而iframe則是在這一個完整的html標籤裏面又嵌套了一個完整的html標籤。
<html>
<body>
<p>Python伊甸園</p>
</body>
</html>
3.看一下中國知網的源碼,發現果然存在一個iframe,所以這個就是中國知網的第三種反爬蟲機制。
五、最後給出中國知網的爬蟲
1.ways.py
import pandas as pd
#AU=王長峯 AND FU=71271031
def get_data():
data_list = pd.read_excel(r"C:\Users\wwb\Desktop\科學基金.xls",
encoding='utf8')
leaders = data_list.leader.values.tolist()
codes = data_list.code.tolist()
results = []
for leader,code in zip(leaders,codes):
result = "AU={} AND FU={}".format(leader,code)
results.append(result)
return results
#results = get_data()
#print(results)
2.main.py
from selenium import webdriver
from lxml import etree
import time
from ways import get_data
import random
def pasre_page(driver):
html = etree.HTML(driver.page_source)
trs = html.xpath('//tr[@bgcolor]')
for tr in trs:
title = tr.xpath('./td//a[@class="fz14"]/text()')[0]
authors = tr.xpath('./td[@class="author_flag"]/a[@class="KnowledgeNetLink"]//text()')
authors = "|".join(authors)
source = tr.xpath('./td//a[@target="_blank"]/text()')[1]
times = tr.xpath('./td[@align="center"]/text()')[0].strip()
database = tr.xpath('./td[@align="center"]/text()')[1].strip()
counted = tr.xpath('./td//span[@class="KnowledgeNetcont"]/a/text()')
if len(counted) == 0:
counted = 0
else:
counted = counted[0]
downloadCount = tr.xpath('./td//span[@class="downloadCount"]/a/text()')
if len(downloadCount) == 0:
downloadCount = 0
else:
downloadCount = downloadCount[0]
data = {
"title":title,
"authors":authors,
"source":source,
"times":times,
"database":database,
"counted":counted,
"downloadCount":downloadCount,
}
datas.append(data)
print(title)
time.sleep(random.uniform(2,4))
driver.switch_to.parent_frame()
search_win = driver.find_element_by_id('expertvalue')
search_win.clear()
time.sleep(random.uniform(2,4))
driver_path = r"C:\Users\wwb\Desktop\chromedriver.exe"
driver = webdriver.Chrome(executable_path=driver_path)
url = "https://www.cnki.net/"
driver.get(url)
home_page = driver.find_element_by_id('highSearch')
home_page.click()
driver.switch_to_window(driver.window_handles[1])
search_page = driver.find_element_by_id('1_3')
search_page.click()
datas = []
results = get_data()
for result in results:
search_win = driver.find_element_by_id('expertvalue')
search_win.send_keys(result)
search_btn = driver.find_element_by_id('btnSearch')
search_btn.click()
iframe = driver.find_element_by_id('iframeResult')
driver.switch_to.frame(iframe)
time.sleep(random.uniform(2,4))
pasre_page(driver)
3.部分結果展示: