requests獲取知網參考文獻
電腦上下載了一堆參考文獻,在論文里插入參考文獻是個麻煩事,要文獻的作者,期刊,期卷,頁數等,開始是一個個pdf點進去看,後來發現知網可以導出參考文獻格式。知網下載下來的pdf格式都是固定的,標題_第一個作者,然後endnote還無法自動識別知網下載下來的caj,pdf信息,因此需要在知網搜索再導出參考文獻格式。
從本地讀取文獻名字:
# 不帶r系統會覺得U是編碼聲明,然後報錯keylist=os.listdir(rC:UsershpDesktop文獻、綜述)for k in keylist: key=k.strip(.pdf).split(_)[0] try: author=k.strip(.pdf).split(_)[1] except: author=
考慮到了文獻名字格式問題,有些其他地方的文獻不是按照標題_作者的形式,加了個try
構建請求頭
請求頭不帶cookie否則會覆蓋session的cookie。
# 不帶cookie的請求頭,從chrome複製的 headers={ "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding":"gzip, deflate, sdch", "Accept-Language":"zh-CN,zh;q=0.8", "Connection":"keep-alive", "Host":"nvsm.cnki.net", "Referer":"http://nvsm.cnki.net/kns/brief/default_result.aspx", "Upgrade-Insecure-Requests":"1", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36", }
直接從chrome複製到1.txt,然後轉換格式,使得符合python的語法,windows下指定encoding,否則會默認使用GBK,從而出錯
with open(1.txt,encoding=utf-8)as f: with open(need.txt, a)as f1: for i in f.readlines(): needed=i.split(:,1) f1.write("{}":"{}".format(needed[0],needed[1].strip())+,+
)
請求文章列表
用了requests.session來處理,好處是cookie可以在不同的請求之間沿用。在搜索框輸入關鍵字,chrome裡面抓包可以發現所需要的文章列表在http://nvsm.cnki.net/kns/brief/brief.aspx...裡面,是一個get的請求,但是直接構造網址請求這個地址會出來 沒有此用戶 類似的提示信息。如果在headers裡面加cookie欄位,複製當前的cookie進去是可以獲得文章列表的,因此分析是狀態的問題。那就用session一個個來請求brief之前的幾個地址,發現post請求SearchHandler.ashx之後再請求brief.aspx就可以獲得想要的結果
# searchHandler的post參數 formdata_searchHandler={很長,不顯示出來,具體看代碼,都是在chrome複製出來然後轉換的 } # Session可以保持請求的狀態,保持不同請求之間cookie沿用相同的cookie s=requests.Session() # post請求之後伺服器才有用戶的記錄,否則無法獲得搜索結果列表,說用戶不存在 bb=s.post(http://nvsm.cnki.net/kns/request/SearchHandler.ashx,data=formdata_searchHandler,headers=headers) # brief里是搜索結果 url=http://nvsm.cnki.net/kns/brief/brief.aspx? parameter={ 很長,不顯示出來,具體看代碼,都是在chrome複製出來然後轉換的 } # 用urlencode構建網址 search=s.get(url+urlencode(parameter),headers=headers)
獲取詳情
採用了scrapy的選擇器比較習慣。網頁元素結構如下
這部分裡面的tbody如果加入到xpath裡面是無法獲得結果的,去掉反而可以,接下來還有一個類似的tr也是加進去不行去掉可以。獲得的網址無法直接訪問,需要變換一下
selector=scrapy.Selector(text=search.text) # 僅僅<tbody>無法被找到 d_url=selector.xpath(//table[@class="GridTableContent"]/tr[2]/td[2]/a/@href).extract_first() # 修改獲得的網址,使得可以正常訪問鏈接 d_url=d_url.replace(/kns,http://kns.cnki.net/KCMS) search=s.get(d_url)
導出參考文獻
詳情頁裡面結構是這樣的
這是一個點擊觸發的js函數,由於是點擊會新建標籤打開新的網址,用chrome抓包就看不到了,新打開的網址是http://kns.cnki.net/kns/ViewPage/viewsave.aspx,再請求一次會說未選擇要存檔的文件。採用fiddle抓包可以發現,其實是向該網址post了一個請求。formfilenames:CJ........ 那一長串就是文件名,因此構造post請求就好了,然後xpath獲取onclick的內容,正則獲得兩個參數
selector=scrapy.Selector(text=search.text) # 導出參考文獻是一個js函數,有兩個參數 網址和文件名,點擊會在新建標籤頁打開新的網址 cankao=selector.xpath(//div[@class="wxTitle"]/div[@class="link"]/a[1]/@onclick).extract_first() # 把網址和文件名分開,之前用『,』連接。search函數需要group() caokao_url=re.search(r.*,cankao).group().split(,) # 獲得的網址和文件名帶單引號,去掉。用fiddle抓包發現新建的標籤頁是post請求的 search=s.post(caokao_url[0].strip(),data={formfilenames:caokao_url[1].strip()})
輸出參考文獻
selector=scrapy.Selector(text=search.text) # 僅僅<tr>用xpath無法識別,可以直接忽略 # text=selector.xpath(//table[@class="mainTable"]/tr[1]/td/text()).extract_first() text=selector.xpath(//table[@class="mainTable"]/td[1]/text()).extract_first() # 輸出參考文獻 print(text)
結果
代碼地址
lyg4795/-cnki-推薦閱讀:
※C4D腳本:根據圖片大小建立平面並賦予貼圖
※用python-pandas作圖矩陣
※20170422 NumPy基礎:數組和矢量計-4
※零基礎入門python爬蟲(一)
※【Python3網路爬蟲開發實戰】1.5.4-RedisDump的安裝