python爬取知网的数据进行各计算机领域学术关注度指数的可视化

python爬取知⽹的数据进⾏各计算机领域学术关注度指数的可视化python爬取知⽹的数据进⾏各计算机领域学术关注度指数的可视化
最近在思考⼈⽣,逛知⽹时发现知⽹会对每个科研关键词进⾏统计,给出⼀个关注度曲线。
于是我就查看⼀些关键词的研究发展情况,但是每⼀次都要⾃⼰更换搜索关键词,再点击进去查看曲线。
作为计算机系的学⽣,这固然不能忍。
于是我决定⽤python把感兴趣的关键词的数据全部爬取下来绘制到⼀张图⾥。
效果如图:
监视器安装简单记录下,下⾯是步骤:
⼀、爬取数据
1.1. 数据来源
点开⼀篇论⽂,会看见摘要下⽅的关键词
随便点击⼀个关键词,就会看到知⽹已经统计好的关注度指数分析。
当我们⿏标聚焦曲线时,就会看见弹窗中显⽰的改点的年份与数据。这⾥的数据就是该关键词在该年份的关注度指数,或者说该年发表的与该关键词相关的论⽂数量。
1.2. 爬取源码
1.2.1. 分析链接
数据到了,我们观察本页⾯的链接
链接很长,url中所含的参数⽐较多,我们去掉⼀些不相关参数,只留下skey="推荐系统"这个关键词试试:
在浏览器输⼊,发现依旧能够获取数据。那么我们只需要替换skey=" "⾥⾯的关键词,就可以得到不同关键词的关注度指数页了。
乳酸环丙沙星氯化钠注:url中 skey=“推荐系统” 与 skey=%E6%8E%A8%E8%8D%90%E7%B3%BB%E7%BB%9F 是等价的,只是在浏览器输⼊时会转码。
很好!此时再定位数据所在的标签就好了!浏览器点击F12打开审查元素,耐⼼寻。发现数据就在⼀个有关键字“renderLineChart”的json数据⾥。
1.2.2. 爬取页⾯数据
这时,我们迫不及待的准备爬取页⾯再拿到数据
拍痧棒
import requests
if __name__ =='__main__':
url="knski/kcms/detail/knetsearch.aspx?sfield=kw&skey=推荐系统"
response = (url)
t.decode('utf-8'))
请求成功了!在结果⾥搜索“renderLineChart”,发现不到!这时候挠掉了⼏根头发。
显然,爬取数据失败了。
为什么失败?可能是该数据并不是静态存储在doc中的,⽽是动态获取的。
1.2.3. 解决爬取js动态数据问题
易揭膜这时候回到浏览器f12界⾯。点击⽹络(network),刷新页⾯,会发现所有的数据请求都在这个列表⾥。226条请求如何到我需要的数据请求呢?
“数据就在⼀个有关键字“renderLineChart”的json数据⾥” 在⽹络页⾯ctrl+f搜索:renderLineChart。
浏览器就⾃动帮我们定位请求所在位置了。
此时我们点击“标头”,就可以看到浏览器告诉我们的请求URL。
链接如下:
这时,我们迫不及待的准备爬取页⾯再拿到数据
import requests
if __name__ =='__main__':
url="knski/kcms/detail/frame/knetlist.aspx?name=推荐系统&infotype=9&codetype=j&catalogName=%E5%85%B3%E6%B3%A8%E5%BA%A 6%E6%8C%87%E6%95%B0%E5%88%86%E6%9E%90&vl=-7Yty5Rksx3cmKbdO0sTT1XnIRr43Xy2xHdd7lZluh_hb-
vEEpRBDQuaXcWzE0YC"
response = (url)
t.decode('utf-8'))
此时发现请求是成功的!返回的内容如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
</head>
<body>
<form name="form1"method="post"action="knetlist.aspx?name=%u63a8%u8350%u7cfb%u7edf&infotype=9&codetype=j&catalogName= %u5173%u6ce8%u5ea6%u6307%u6570%u5206%u6790&vl=-7Yty5Rksx3cmKbdO0sTT1XnIRr43Xy2xHdd7lZluh_hb-vEEpRBDQuaXcWzE0YC"id="f orm1">
<input type="hidden"name="__VIEWSTATE"id="__VIEWSTATE"value="/wEPDwUKLTUxMTcwNzgxMGRkjhjYRPTUl6/K/rznK1hDjhK9Xj3ZhdVm0yS5/MS d+tk="/>
<input type="hidden"name="__VIEWSTATEGENERATOR"id="__VIEWSTATEGENERATOR"value="30B6FF1C"/>
<div>
</div>
</form>
</body>
</html>
但是为什么没有我们要的数据?这时⼜挠掉了⼏根头发。
其实就是⽬标⽹站的反爬机制了。进⾏数据请求时,有时候会返回⼀些代码,或者空⽩,或者缺失的数据,很可能是因为⽬标⽹站的反爬⾍机制。你直接url来请求,我拒绝给你数据。
这时候就需要伪装⼀下了。
伪装成正常浏览器进⾏爬⾍
伪装的⽅式很简单,添加假请求头fake_headers,再把fake_headers放到get()的参数⾥就好了。
我先是添加了cookie,发现没⽤。⼜添加了Referer就成功了。这些信息在浏览器f12界⾯都能到。
#伪造浏览器请求头
#cookie = 'Ecp_ClientId=5210628102801308911;cnkiUserKey=b261114d-5456-f7a0-d218-29c90a247b35;Ecp_ClientIp=58.34.66.42;_pk_ref=%5B%22 %22%2C%22%22%2C1627001927%2C%22https%3A%2F%2Fcn.bing%2F%22%5D;ASP.NET_SessionId=wx2bvmuixh3bq3r5meb5tnk5;SID_kns8=12 3123;CurrSortFieldType=desc;SID_kcms=124101;CurrSortField=%e5%8f%91%e8%a1%a8%e6%97%b6%e9%97%b4%2f(%e5%8f%91%e8%a1%a8%e6% 97%b6%e9%97%b4%2c%27TIME%27);Ecp_IpLoginFail=21072358.34.66.42, 10.210.0.12;_pk_id=fc0ebc8f-840b-44c6-b064-37d1205b7bcc.1624847325.
3.1627002597.1627001927.;SID_kns_new=kns123110;'
fake_headers ={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36',
#'Cookie':cookie,  #cookie测试,不需要cookie也可获取
#'Referer':'knski/kcms/detail/knetsearch.aspx?sfield=kw&skey=%E5%8C%BA%E5%9D%97%E9%93%BE&code=&v=9tzIsR7LVgUKQ_Uc qcy13H0PVvC_8a71XDfdwE8ntLnmoNnjXXC3V0UrNnvhguYG'
'c':'wwwki/'#Referer测试,需要Referer,否则获取值为空
}
response =  (targetUrl,headers =fake_headers)
伪装的很完美,数据就在我们的返回值⾥了。结果:
<html>
<head>
...省略
</head>
<body onload="ResezeParent(0);SetParentCatalog(); closePopMore(1)"><script type="text/javascript"src="piccacheki/kdn/kcms8/detail/js/mi n/WideScreen.min.js"></script><h2 class="title1"id="catalog_GZDZSFX">
关注度指数分析<span class="desc">(检索范围:源数据库,包括期刊库、博⼠论⽂库、硕⼠论⽂库、报纸库、会议库)</span></h2>
<div class="titleSide"><a class="more"onclick="TurnPageToKnsApp('cidx')">
查看更多指数分析结果
</a></div>
<div class="listcont">
<div id="KwsChart"></div><script>
RenderLineChart([{name:"推荐系统",data:[[1989,1],[1995,1],[1999,1],[2000,1],[2001,2],[2002,8],[2003,14],[2004,24],[2005,60],[2006,80],[2007,109],[2 008,117],[2009,138],[2010,192],[2011,234],[2012,281],[2013,437],[2014,573],[2015,741],[2016,846],[2017,941],[2018,1043],[2019,1063],[2020,917],[2021, 165]]}]);
</script></div>
</body>
</html><!-- 后台处理耗时:15.625 毫秒 -->
Process finished with exit code 0
1.3. 批量爬取
定义⼀个列表存储⾃⼰感兴趣的关键词,遍历替换url中的关键词。
定义函数getInfo(),传⼊url进⾏请求操作。
为了爬取过程的流畅性,进⾏异常处理,异常时回调,防⽌中断。
import requests
keyword=['机器学习','深度学习','物联⽹','云计算','计算模型','⼤数据','数学建模','图像处理','计算机视觉','计算机体系结构','理论计算机科学','计算机科学','区块链', '⼈⼯智能']
def getInfo(targetUrl):
#伪造浏览器请求头
fake_headers ={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36',
#'Cookie':cookie,  #cookie测试,不需要cookie也获取
#'Referer':'knski/kcms/detail/knetsearch.aspx?sfield=kw&skey=%E5%8C%BA%E5%9
D%97%E9%93%BE&code=&v=9tzIsR7LVgUKQ_Uc qcy13H0PVvC_8a71XDfdwE8ntLnmoNnjXXC3V0UrNnvhguYG'
'Referer':'wwwki/'#Referer测试,需要Referer,否则获取值为空
}
try:
response =  (targetUrl,headers =fake_headers)
print("⽬标⽹站:"+ targetUrl +";"+"\n请求结果代码:"+str(response.status_code))
except:
getInfo(targetUrl)#异常时回调
return response
if __name__ =='__main__':
for i in range(len(keyword)):
url ="knski/kcms/detail/frame/knetlist.aspx?name="+ keyword[i]+"&infotype=9&codetype=j&catalogName=%E5%85%B3%E6%B3%A8 %E5%BA%A6%E6%8C%87%E6%95%B0%E5%88%86%E6%9E%90&vl=9tzIsR7LVgUKQ_Ucqcy13H0PVvC_8a71XDfdwE8ntLnvQsAEFaVMjFwHdnwGLpb u"
response = getInfo(url)
t.decode('utf-8'))
⼆、解析数据
以上获取到的数据⾮常混乱,是html格式的数据,我们需要解析取出其中我们需要的。
定义⼀个函数:prase(response),将请求的返回值传⼊进⾏解析。解析过程代码有详细注释。
注意解析时需要引⼊⼀些库。没有的库可⾃⾏pip安装。
from bs4 import BeautifulSoup
import re
import json
#添加全局变量,存储解析后得到的数据
year_data_all =[]
keyword_all =[]
def prase(response):
'''
"""
调式阶段,把⽹页内容存⾄本地进⾏解析。避免写代码调试时⼀直向⽬标服务器请求。
解析完成后再将此段代码注释,添加:html = t.decode('utf-8')
将请求与解析合并
"""
# 以写格式打开⽂件
UnParseResponse = open('UnParseResponse.html', 'w', encoding="utf-8")
# 将初步请求结果写⼊⽂件
UnParseResponse.t.decode('utf-8'))
UnParseResponse.close()
# 以读⽅式打开⽂件名为html_file1.html的⽂件
UnParseResponse = open('UnParseResponse.html', 'r', encoding="utf-8")
# 把⽂件的内容全部读取出来并赋值给html变量
html = ad()
# 关闭⽂件对象
UnParseResponse.close()
'''
html = t.decode('utf-8')#当上述代码注释时,将这条添加上
# 初始化BeautifulSoup
soup = BeautifulSoup(html,'lxml')
#print(soup)  打印请求到的数据
div=soup.find('div',class_ ='listcont')
data = div.find('script').string
#print(data)  #需要的字符串,这⾥还可以尝试将数据转化成json,但本⼈习惯使⽤字符串提取的⽅式    name = re.findall("name:\"(.+?)\"",str(data))#从字符串中提取出关键词名称
year_data = re.findall("data:(.+?)}",str(data))# 从字符串中提取出年份与数量 type:str
#防⽌不到字符串从⽽返回的列表为空,添加异常处理
try:
name = name[0]
keyword_all.append(name)
year_data = json.loads(year_data[0])# 将字符串转换为列表 type:list shpae:[[]]
year_data_all.append(year_data)
制作智能卡
#print(year_data_all)
#print(keyword_all)
except:
print("发⽣异常,字符串提取错误:name="+str(name)+"year_data="+str(year_data))
现在我们得到了两个列表,⼤概的形式时这样的:
keyword_all=['机器学习','深度学习',...,'⼈⼯智能']
这是⼀个三层嵌套列表:
year_data_all = [
[[1999,1],[2000,2],...,[年份,数值]],
[[1987,5],[1988,7],...,[年份,数值]],
...,
[[1977,212],[1978,145],...,[年份,数值]]
]
变压器油箱
解析完之后记得在main的for循环中加上。

本文发布于:2024-09-21 14:26:15,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/2/129189.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   关键词   请求   解析   需要
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议