知网

这目录直接提取

<a class="fz14" href="/kns/detail/detail.aspx?QueryID=30&CurRec=2&dbcode=SOPD&dbname=SOPD2018&filename=USD828895(S1)" target="_blank">Trigger mechanism</a>
<a class="fz14" href="/kns/detail/detail.aspx?QueryID=30&CurRec=3&dbcode=SOPD&dbname=SOPD2018&filename=US10076922(B2)" target="_blank">Customizable document for producing a security document, customized security document and production of such a security document</a>
#这个是获取第二页的数据的方法,需要传入上面处理出来的页数
def fanye(self,page):
#第一页已经抓取了,从第二页开始,然后到最后一页
for i in range(2,page+1):
#构造第二页的url
page_url='http://kns.cnki.net/kns/brief/brief.aspx?curpage={0}&RecordsPerPage=50&QueryID=0&ID=&turnpage=1&tpagemode=L&dbPrefix=SCOD&Fields=&DisplayMode=listmode&PageName=ASP.brief_result_aspx&isinEn=0#J_ORDER&'.format(i)
response=self.connect(page_url)
soup=bs(response.text,'html.parser')
#调用上面的获取详情的函数
self.xq_url_get(soup)

<a href="?curpage=2&RecordsPerPage=20&QueryID=30&ID=&turnpage=1&tpagemode=L&dbPrefix=SCOD&Fields=&DisplayMode=listmode&PageName=ASP.brief_result_aspx&isinEn=0#J_ORDER&" title="键盘的“← →”可以实现快速翻页">2</a>
<a href="?curpage=3&RecordsPerPage=20&QueryID=30&ID=&turnpage=1&tpagemode=L&dbPrefix=SCOD&Fields=&DisplayMode=listmode&PageName=ASP.brief_result_aspx&isinEn=0#J_ORDER&" title="键盘的“← →”可以实现快速翻页">3</a>
目录提取,有img的有下一层。



目录是 NaviGroup
其这几个参数比较重要
Host: kns.cnki.net
Referer: http://kns.cnki.net/kns/brief/result.aspx?dbprefix=CISD&catalogName=ZJCLS
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
下面几个需要构造url
Query string parameters
code: A
tpinavigroup: CISDtpiresult
catalogName: ZJCLS
__: Fri Oct 26 2018 18:31:53 GMT+0800 (中国标准时间)

其构造函数放在下面
#底层的目录进行处理
def children_tag(self):
#由于是post请求,所以需要先构造相应的data
from_data={
'ua':1.25,
'PageName': 'ASP.brief_result_aspx',
'DbPrefix': 'SCOD',
'DbCatalog': '专利数据总库',
'ConfigFile': 'SCOD.xml',
'db_opt': 'SCOD',
'db_value': '中国专利数据库,国外专利数据库',
'his': '0',
'__': '%s %s' % (time.strftime('%a %b %d %Y %H:%M:%S GMT+0800'), ' (中国标准时间)')}
#遍历底层的目录
for i in self.mulu_list:
#底层目录的编号
print(i)
#需要传入的值,所以用字典的添加方式将值添加到from_data
from_data['NaviCode']=i
#这个访问的网站是做打开数据库的操作,让cookies出现在他们网页地图上,否则无法得到相应的数据
ss = self.connect(searchHandler_url, data=from_data, mothed='POST')
#访问失败则重新访问一次,如果还不可以则打印相应的url
if ss==404:
time.sleep(random.randint(5,7))
ss = self.connect(searchHandler_url, data=from_data, mothed='POST')
if ss==404:
print(searchHandler_url)
else:
#成功则调用下面的函数,获得相应的数据页面
self.data_get()
else:
self.data_get()

Search页面的 fromdate 也很重要
action:
NaviCode: A
catalogName: ZJCLS
ua: 1.25
isinEn: 0
PageName: ASP.brief_result_aspx
DbPrefix: CISD
DbCatalog: 标准数据总库
ConfigFile: CISD.xml
db_opt: CISD
his: 0
__: Fri Oct 26 2018 18:37:02 GMT+0800 (中国标准时间)
import requests, random,re
from settings import *
from multiprocessing import Process,queues
from bs4 import BeautifulSoup as bs
searchHandler_url='http://kns.cnki.net/kns/request/SearchHandler.ashx'
data_url='http://kns.cnki.net/kns/brief/brief.aspx'
mulu_list=['A','B','C','D','E','F','G','H','I','J']
# 连接类(——主要作用用requests访问页面——)
class Conect(object):
#连接方法,用requests访问网站,有两种方法(post和get)
def connect(self, url, proxies=None, mothed='GTE', data=None):
#无法访问进行3次尝试,如果还不行,就返回404
for z in range(1, 4):
#异常捕获,否则无法访问则会报错
try:
if mothed == 'GTE':
response = self.s.get(url, headers=self.headers,data=data, proxies=proxies, timeout=90)
else:
response = self.s.post(url, data=data, headers=self.headers, proxies=proxies, timeout=90)
#错误则进行休眠
except Exception:
print('无法连接网络,正在进行第%d次尝试' % z)
time.sleep(random.randint(3, 7))
#判断已经访问错误几次了,如果大于等于3,则返回404,反之则跳过
if z < 3:
pass
else:
print('三次未访问成功的网站:', url)
# 这里将无法访问3次则记录错误信息日志记录
return 404
#网页中可能本身存在404,找不到网页的情况,这种时候直接返回404
else:
if response.status_code == 404:
return 404
#正常情况,返回的是网页源码,解码格式我直接采用了utf-8,可根据网站需要更换
else:
response.encoding = 'utf-8'
return response
#主程序
class zhiwang_zhuanli(Conect):
#创建Session,可自动记录访问的cookies
s = requests.Session()
#访问的请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
'Host': 'login.cnki.net',
'Referer': 'http://www.cnki.net/'
}
#这个列表是用来装底层目录的列表
mulu_list=[]
#由于是多进程,所以需要类接收一个参数,最外层目录编号
def __init__(self,code_abc):
self.__go__(code_abc)
# 运行程序(一般多线程都放在这个函数里面)
def __go__(self,code_abc):
#由于我无法确定每个有多少层目录,所以我用递归的方式,调用了反复调用自身,传入的长度首先是2
lenge=len(code_abc)
while lenge>0:
#对code_abc进行重新赋值,可以减小反复占用内存
code_abc=self.mulu(code_abc)
#对lenge重新赋值,重复调用本身函数,直到无二级以上的分类为止
lenge=len(code_abc)
#处理底层目录
self.children_tag()
#未用上,这个本来是可以改变Session的cookies,但是我发现后面也可以获得cookies
def cookies_get(self):
rsponse=404
while rsponse==404:
rsponse=self.connect(login_url,proxies=self.proxies)
time.sleep(random.randint(4,10))
#对目录进行处理的方法,每次访问一层,直到全部底层的目录的都加入到self.mulu_list
def mulu(self,code_abc):
#修改referer,否则无法拿到值
self.headers['Referer'] = 'http://kns.cnki.net/kns/brief/result.aspx?dbprefix=SCOD'
#host也不同,所以要做修改
self.headers['Host']='kns.cnki.net'
#创建一个非底层目录保存列表
f_list=[]
# 用遍历的方式来访问每个非底层的目录
for i in code_abc:
#构造需要访问的url
mulu_url_pj=mulu_url+'?code='+i+'&tpinavigroup='+'SCODtpiresult'+'&__='+time.strftime('%a %b %d %Y %H:%M:%S GMT+0800')
#访问相应的url
sz=self.connect(mulu_url_pj)
#判断,如果访问为404,则pass
if sz==404:
print('目录访问失败!')
else:
#访问成功的进行解析
soup=bs(sz.text,'html.parser')
dd=soup.findAll('dd')
for dd_tag in dd:
img=dd_tag.find('img')
xuhao_tag=dd_tag.find('a').get('onclick')
if img==None:
#提取序号
bianhao=self.dd_re(xuhao_tag)
#将底层的目录放在类的列表中
self.mulu_list.append(bianhao)
else:
#将非底层的目录放在一个列表中
bianhao=self.dd_re(xuhao_tag)
f_list.append(bianhao)
#返回非底层的列表
return f_list
# 对编号进行裁剪,得到相应的值
def dd_re(self, string):
xuhao = re.split('\'', string)[1]
return xuhao
#底层的目录进行处理
def children_tag(self):
#由于是post请求,所以需要先构造相应的data
from_data={
'ua':1.25,
'PageName': 'ASP.brief_result_aspx',
'DbPrefix': 'SCOD',
'DbCatalog': '专利数据总库',
'ConfigFile': 'SCOD.xml',
'db_opt': 'SCOD',
'db_value': '中国专利数据库,国外专利数据库',
'his': '0',
'__': '%s %s' % (time.strftime('%a %b %d %Y %H:%M:%S GMT+0800'), ' (中国标准时间)')}
#遍历底层的目录
for i in self.mulu_list:
#底层目录的编号
print(i)
#需要传入的值,所以用字典的添加方式将值添加到from_data
from_data['NaviCode']=i
#这个访问的网站是做打开数据库的操作,让cookies出现在他们网页地图上,否则无法得到相应的数据
ss = self.connect(searchHandler_url, data=from_data, mothed='POST')
#访问失败则重新访问一次,如果还不可以则打印相应的url
if ss==404:
time.sleep(random.randint(5,7))
ss = self.connect(searchHandler_url, data=from_data, mothed='POST')
if ss==404:
print(searchHandler_url)
else:
#成功则调用下面的函数,获得相应的数据页面
self.data_get()
else:
self.data_get()
#获得数据列表的网站,这个只是访问第一页,后面几页需要重新构造
def data_get(self):
#这里由于headers都是一样的,所以我没有做修改
url=data_url+'?'+'pagename=ASP.brief_result_aspx&'+'isinEn=0&'+'dbPrefix=SCOD&'+'dbCatalog=%e4%b8%93%e5%88%a9%e6%95%b0%e6%8d%ae%e6%80%bb%e5%ba%93&'+"ConfigFile=SCOD.xml&"+'research=off&'+'S=1'
response=self.connect(url)
#访问失败则跳过
if response==404:
print(url)
else:
#访问成功的则对页面做后面的处理
page=self.data_re(response)
self.fanye(page)
#获取页数的函数
def data_re(self,response):
#解析打开的网页
text=response.text
soup=bs(text,'html.parser')
#抓取包含页数的地方,如果抓不到,则代表没有第二页,则返回0
page=soup.find('span',{'class':'countPageMark'})
if page==None:
#这里调用的方法是获取文章详情的url
self.xq_url_get(soup)
return 0
else:
self.xq_url_get(soup)
#由于抓取到的是字符串,而且都是1/%d,这种格式,所以我直接裁掉前面的,得到页数
num=re.sub('1/','',page.text)
#返回int型页数
return int(num)
#这个是获取第二页的数据的方法,需要传入上面处理出来的页数
def fanye(self,page):
#第一页已经抓取了,从第二页开始,然后到最后一页
for i in range(2,page+1):
#构造第二页的url
page_url='http://kns.cnki.net/kns/brief/brief.aspx?curpage={0}&RecordsPerPage=50&QueryID=0&ID=&turnpage=1&tpagemode=L&dbPrefix=SCOD&Fields=&DisplayMode=listmode&PageName=ASP.brief_result_aspx&isinEn=0#J_ORDER&'.format(i)
response=self.connect(page_url)
soup=bs(response.text,'html.parser')
#调用上面的获取详情的函数
self.xq_url_get(soup)
#每页中都有文章详情的链接,所以用这个方法提取
def xq_url_get(self,soup):
xq_url_tag = soup.find('table', {'class': "GridTableContent"})
xq_url_list = xq_url_tag.findAll('a')
for url in xq_url_list:
# print('文章网站:', 'http://kns.cnki.net' + url.get('href'))
pass
if __name__ == '__main__':
#五个进程,调试的时候我用的是一个
# for i in range(5):
for i in range(1):
P1=Process(target=zhiwang_zhuanli,args=([mulu_list[i],mulu_list[9-i]],))
P1.start()
网友评论