CNKI作为国文最大的数据库,虽然下载文章是需要登陆的,但是只除了全文外还有很多有价值的信息,包括文章名,作者,基金还有摘要,都可以作为重要数据进行匿名爬取,先写个简单的出来,之后有空再建个关联的数据吧
因为闲放在一个文件中太乱所以把他们分开两个文件,一个为主文件Crawl_cnki.py,一个为参数文件Parameters.py。文件包:https://github.com/shikanon/CNKI_crawler
参数文件主要是对提交参数做分析,对CNKI查询主要提交参数进行说明:
# -*- coding: cp936 -*- #SU主题,TI篇名,KY关键词,AB摘要,FT全文 #笔者通过chorme抓包获取提交参数,值得注意的是CNKI为utf-8编码而非gbk编码 #而因为文档中出现中文所以默认为gbk编码了,所以中文需要先gbk解码再进行utf-8编码 import time def ToUtf(string): return string.decode('gbk').encode('utf8') search={'SU':'分异','TI':'分异'} DbCatalog=ToUtf('中国学术文献网络出版总库') magazine=ToUtf('地理学报') times=time.strftime('%a %b %d %Y %H:%M:%S')+' GMT+0800 (中国标准时间)' parameter={'ua':'1.21', 'PageName':'ASP.brief_result_aspx', 'DbPrefix':'SCDB', 'DbCatalog':DbCatalog, 'ConfigFile':'SCDB.xml', 'db_opt':'CJFQ,CJFN,CDFD,CMFD,CPFD,IPFD,CCND,CCJD,HBRD', 'base_special1':'%', 'magazine_value1':magazine, 'magazine_special1':'%', 'his':'0', '__':times} def BuildQuery(value): par={'txt_1_relation':'#CNKI_AND','txt_1_special1':'='} i=0 for v in value: i=i+1 par['txt_%d_sel'%i]=v par['txt_%d_value1'%i]=ToUtf(value[v]) par['txt_%d_relation'%i]='#CNKI_AND' par['txt_%d_special1'%i]='=' return par def parameters(): parameters=dict(parameter,**BuildQuery(search)) return parameters
查询参数可以自己定义search,主要用到的还是“U主题,TI篇名,KY关键词,AB摘要,FT全文”这几项,如果还需要更多参数可以自己抓包,Chorme挺方便的。
下面是主程序:
# -*- coding: cp936 -*- import urllib,urllib2,cookielib,httplib,time,re,Parameters def ToUtf(string): return string.decode('gbk').encode('utf8') class CNKI: def search(self): #两个发送请求的主网页,知网需要两次发送请求,一次为参数请求,一次为返回页面请求 url='http://epub.cnki.net/KNS/request/SearchHandler.ashx?action=&NaviCode=*&' url2='http://epub.cnki.net/kns/brief/brief.aspx?' #生成cookie cookie = cookielib.CookieJar() #创建一个新的opener来使用cookiejar opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie),urllib2.HTTPHandler) #构建头结构,模拟浏览器 #httplib.HTTPConnection.debuglevel = 1 hosturl='http://epub.cnki.net/kns/brief/result.aspx?dbprefix=scdb&action=scdbsearch&db_opt=SCDB' headers={'Connection':'Keep-Alive', 'Accept':'text/html,*/*', 'User-Agent':'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36', 'Referer':hosturl} #再将参数url编码,编码顺序并不影响提交成果 parameters=Parameters.parameters() postdata=urllib.urlencode(parameters) #构建第二次提交参数,不过貌似这些参数对返回值没有影响,尝试了修改keyValue和spvalue依然能正常返回 query_string=urllib.urlencode({'pagename':'ASP.brief_result_aspx','DbCatalog':'中国学术文献网络出版总库', 'ConfigFile':'SCDB.xml','research':'off','t':int(time.time()), 'keyValue':'','dbPrefix':'SCDB', 'S':'1','spfield':'SU','spvalue':'', }) #实施第一步提交申请 req=urllib2.Request(url+postdata,headers=headers) html=opener.open(req).read() with open('web1.html','w') as e: e.write(html) #第二步提交申请,第二步提交后的结果就是查询结果 req2=urllib2.Request(url2+query_string,headers=headers) result2 = opener.open(req2) html2=result2.read() #打印cookie值,如果需要下载文章的话还需要登陆处理 for item in cookie: print 'Cookie:%s:/n%s/n'%(item.name,item.value) with open('web2.html','w') as e: e.write(html2) print self.Regular(html) def Regular(self,html): reg='<a href="(.*?)"\ttarget' comlists=re.findall(re.compile(reg),html) return comlists cnki=CNKI() cnki.search()
知网网址需要两次Request,第一次提交是获取参数页,第二次其实提交Request是作为请求信息返回,参数值好像并没有什么用,我尝试改了也能正常返回,匹配规则主要是用(.*?)抽取链接,之后对新的链接的写入就没有写了.