CNKI小爬虫(Python)

Stella981
• 阅读 488

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是作为请求信息返回,参数值好像并没有什么用,我尝试改了也能正常返回,匹配规则主要是用(.*?)抽取链接,之后对新的链接的写入就没有写了.

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这