一、寫在前面
馬上要畢業了兄弟們,畢業論文是個麻煩事,論文要的資料得一條一條去網上查看,那多浪費時間,咱直接寫個爬蟲,批量下載慢慢看,不舒服?
使用軟件
Python和pycharm就可以了,版本的話都行,只要你別用python2。
模塊
requests #模擬請求 Selenium # 瀏覽器自動化操作
win+r打開搜索框,輸入cmd按確定打開命令提示符窗口,輸入pip install 加上你要安裝的模塊名, 回車即可安裝,下載速度慢就換國內鏡像源。
然后要下載一個谷歌瀏覽器驅動,版本跟你的瀏覽器最相近的那個就行。
不會的看我置頂文章。
頁面分析
首先分析一下知網頁面元素,我們一般是在首頁輸入框中輸入你想搜的內容,然后跳轉到搜索頁面。
我們通過瀏覽器的檢查頁面,得到輸入框和搜索圖標的XPATH分別為:
input_xpath = '/html[1]/body[1]/div[1]/div[2]/div[1]/div[1]/input[1]' button_xpath = '/html[1]/body[1]/div[1]/div[2]/div[1]/div[1]/input[2]'
在輸入框輸入要搜索的內容,操作搜索按鈕轉到結果頁。
以搜索Python為例,共找到15,925條,300頁,每頁中包含20個條目,每個條目包含題目、作者、來源等等內容。
通過對當前頁面分析發現每個條目對應的的xpath的規律
/html[1]/body[1]/div[5]/div[2]/div[2]/div[2]/form[1]/div[1]/table[1]/tbody[1]/tr[1]/td[2]
就是倒數第二個標簽數字代表本頁的第幾個條目,最后一個標簽 2 - 6 分別代表題目、作者、來源、發表時間和數據庫。在當前頁面無法或者文獻的摘要信息,下載鏈接,需要進一步點擊進入相關文獻條目。
進入詳情頁面后,根據class name:abstract-text 能夠很容易定位到摘要的文本,class name: btn-dlcaj 定位到下載鏈接,其他元素也是一樣的。
完成面分析后就可以開始寫代碼了!
導入要用的庫
import time from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from urllib.parse import urljoin
創建瀏覽器對象,設置相關參數
get直接返回,不再等待界面加載完成
desired_capabilities = DesiredCapabilities.CHROME desired_capabilities["pageLoadStrategy"] = "none"
設置谷歌驅動器的環境
options = webdriver.ChromeOptions()
設置chrome不加載圖片,提高速度。
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
設置不顯示窗口
options.add_argument('--headless')
創建一個谷歌驅動器
driver = webdriver.Chrome(options=options)
設置搜索主題
theme = "Python"
設置所需篇數
papers_need = 100
打開頁面搜索關鍵詞
打開頁面
driver.get("https://www.****.net")
網址我屏蔽了,各位自己換一下換成最大的那個查文獻論文的網站。
傳入關鍵字
WebDriverWait( driver, 100 ).until( EC.presence_of_element_located( (By.XPATH ,'''//*[@id="txt_SearchText"]''') ) ).send_keys(theme)
點擊搜索
WebDriverWait( driver, 100 ).until( EC.presence_of_element_located( (By.XPATH ,"/html/body/div[1]/div[2]/div/div[1]/input[2]") ) ).click() time.sleep(3)
點擊切換中文文獻
WebDriverWait( driver, 100 ).until( EC.presence_of_element_located( (By.XPATH ,"/html/body/div[5]/div[1]/div/div/div/a[1]") ) ).click() time.sleep(1)
獲取總文獻數和頁數
res_unm = WebDriverWait( driver, 100 ).until( EC.presence_of_element_located( (By.XPATH ,"/html/body/div[5]/div[2]/div[2]/div[2]/form/div/div[1]/div[1]/span[1]/em") ) ).text
去除千分位里的逗號
res_unm = int(res_unm.replace(",",'')) page_unm = int(res_unm/20) + 1 print(f"共找到 {res_unm} 條結果, {page_unm} 頁。")
解析結果頁
賦值序號,控制爬取的文章數量。
count = 1
當爬取數量小於需求時,循環網頁頁碼。
while count <= papers_need:
等待加載完全,休眠3S。
在適當的地方加上 time.sleep(3) 延時幾秒,既可以等待頁面加載,也可以防止爬取太快被封IP。
time.sleep(3) title_list = WebDriverWait( driver, 10 ).until( EC.presence_of_all_elements_located( (By.CLASS_NAME ,"fz14") ) )
循環網頁一頁中的條目
for i in range(len(title_list)): try: term = count%20 # 本頁的第幾個條目 title_xpath = f"/html[1]/body[1]/div[5]/div[2]/div[2]/div[2]/form[1]/div[1]/table[1]/tbody[1]/tr[{term}]/td[2]" author_xpath = f"/html[1]/body[1]/div[5]/div[2]/div[2]/div[2]/form[1]/div[1]/table[1]/tbody[1]/tr[{term}]/td[3]" source_xpath = f"/html[1]/body[1]/div[5]/div[2]/div[2]/div[2]/form[1]/div[1]/table[1]/tbody[1]/tr[{term}]/td[4]" date_xpath = f"/html[1]/body[1]/div[5]/div[2]/div[2]/div[2]/form[1]/div[1]/table[1]/tbody[1]/tr[{term}]/td[5]" database_xpath = f"/html[1]/body[1]/div[5]/div[2]/div[2]/div[2]/form[1]/div[1]/table[1]/tbody[1]/tr[{term}]/td[6]" title = WebDriverWait( driver, 10 ).until( EC.presence_of_element_located((By.XPATH ,title_xpath) ) ).text authors = WebDriverWait( driver, 10 ).until( EC.presence_of_element_located((By.XPATH ,author_xpath) ) ).text source = WebDriverWait( driver, 10 ).until( EC.presence_of_element_located((By.XPATH ,source_xpath) ) ).text date = WebDriverWait( driver, 10 ).until( EC.presence_of_element_located((By.XPATH ,date_xpath) ) ).text database = WebDriverWait( driver, 10 ).until( EC.presence_of_element_located((By.XPATH ,database_xpath) ) ).text
點擊條目
title_list[i].click()
獲取driver的句柄
n = driver.window_handles
driver切換至最新生產的頁面
driver.switch_to_window(n[-1])
開始獲取頁面信息
# title = WebDriverWait( driver, 10 ).until( EC.presence_of_element_located((By.XPATH ,"/html/body/div[2]/div[1]/div[3]/div/div/div[3]/div/h1") ) ).text # authors = WebDriverWait( driver, 10 ).until( EC.presence_of_element_located((By.XPATH ,"/html/body/div[2]/div[1]/div[3]/div/div/div[3]/div/h3[1]") ) ).text institute = WebDriverWait( driver, 10 ).until( EC.presence_of_element_located((By.XPATH ,"/html[1]/body[1]/div[2]/div[1]/div[3]/div[1]/div[1]/div[3]/div[1]/h3[2]") ) ).text abstract = WebDriverWait( driver, 10 ).until( EC.presence_of_element_located((By.CLASS_NAME ,"abstract-text") ) ).text try: keywords = WebDriverWait( driver, 10 ).until( EC.presence_of_element_located((By.CLASS_NAME ,"keywords") ) ).text[:-1] except: keywords = '無' url = driver.current_url
獲取下載鏈接
link = WebDriverWait( driver, 10 ).until( EC.presence_of_all_elements_located((By.CLASS_NAME ,"btn-dlcaj") ) )[0].get_attribute('href') link = urljoin(driver.current_url, link)
寫入文件
res = f"{count}\t{title}\t{authors}\t{institute}\t{date}\t{source}\t{database}\t{keywords}\t{abstract}\t{url}".replace("\n","")+"\n" print(res) with open('CNKI_res.tsv', 'a', encoding='gbk') as f: f.write(res)
跳過本條,接着下一個。如果有多個窗口,關閉第二個窗口, 切換回主頁。
except: print(f" 第{count} 條爬取失敗\n") continue finally: n2 = driver.window_handles if len(n2) > 1: driver.close() driver.switch_to_window(n2[0])
計數,判斷需求是否足夠。
count += 1 if count == papers_need:break
切換到下一頁
WebDriverWait( driver, 10 ).until( EC.presence_of_element_located( (By.XPATH ,"//a[@id='PageNext']") ) ).click()
關閉瀏覽器
driver.close()
# 到這里所有的功能都實現了,我還給大家准備了這些資料,直接在群里就可以免費領取了。 # 一群:872937351 (群滿了的話加二群) # 二群:924040232 # python學習路線匯總 # 精品Python學習書籍100本 # Python入門視頻合集 # Python實戰案例 # Python面試題 # Python相關軟件工具/pycharm永久激活
兄弟們,記得隨手三連,你的助力是我更新的動力~