#最近没有写东西,因为在学一些很潮的东西。昨天看到一个某网的文章信息觉得挺有意思,在网上找了好久都没有找到好用的代码,于是自己写了一个
需求:文章的标题,作者,网页链接
1.数据展示
2.爬虫思路
1.从官网搜索页面抓取
首先打开官网,搜索关键词‘计算机’查看页面的url并没有和计算机有关的信息,所以文章信息不在官网是异步加载,f12打开开发者模式.win+r刷新页面查看信息
在xhr的筛选下面可以看到如下返还的数据,点击预览可以看到我们要的数据果然在里面
查看标头是一个post请求,携带的信息我们与另外一个检索页面的信息进行对比,发现里面有一些随机数值所以不能直接进行post请求来获取数据
2.selenium自动化
到这我第一个想到的就是selenium自动化,直接用浏览器用发送信息肯定不会出错的,直接将信息抓出来
在写代码的时候却始终无法定位到所在的所在的标签属性,尝试了好长时间搞不出来数据
#可能还是我的功力不够吧
3.同等级检索链接进行检索
又是找了好长时间,终于找到了一个检索链接可以检索出原来一样的信息。
csdn不好发链接,就在下面
#https://kns.cnki.net/kns8/defaultresult/index
通过对它进行分析,同样的源码没有信息,同样的是异步加载,不一样的是请求的链接是get请求
这样就不用再加post了。
对这个请求URL进行请求,会转到一个新的页面里,再次查看信息数据就在源码里
这样我们通过requests对这个链接发起请求,状态码200正常.输出源码信息却什么都没有。
所以是有反爬的,我们来反反爬
首先添加UA.没有信息,
再次添加referer.没有信息,
我们添加cookie.终于获取到了数据。
但是我们要爬取的页面不止一页,我们打开第二页文档筛选里也出现了新数据,查看它的URL是否能进行多页查询
请求 URL: https://kns.cnki.net/kns/brief/brief.aspx?curpage=2&RecordsPerPage=50&QueryID=2&ID=&turnpage=1&tpagemode=L&dbPrefix=CJFQ&Fields=&DisplayMode=listmode&PageName=ASP.brief_result_aspx&isinEn=1&
第二页与第三页的区别在于curpage=2这一个数字,我们只需要进行遍历就可以对每一页发起请求获取源码筛选数据
#注意我后面在测试的时候发现每一次检索的cookie都不一样,在变化所以需要对cookie进行更新
3.通过信息对代码进行编写
我们找到检索后的携带信息的URL通过requests模块对它进行请求,添加所需的请求头cookie与UA和referer
import requests
import re
head = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.26',
'Referer': 'https://kns.cnki.net/kns/brief/result.aspx'
}
cookie = {
'Cookie':
'Ecp_ClientId=d221029142801567465; knsLeftGroupSelectItem=1%3B2%3B; Ecp_loginuserjf=urd1023@163.com; Ecp_ClientIp=43.242.155.3; RsPerPage=50; KNS_DisplayModel=listmode@CFLS; dsorder=download; ASP.NET_SessionId=4v2todmpqqfztxlrskewodns; SID_kns=126008; _pk_ref=%5B%22%22%2C%22%22%2C1667271037%2C%22https%3A%2F%2Fwww.cnki.net%2F%22%5D; _pk_ses=*; SID_kcms=025126024; SID_kns_new=kns25128005; SID_kinfo=126002; Ecp_IpLoginFail=22110143.242.155.24; SID_klogin=126002; KNS_SortType=; _pk_id=bbc9cfb9-d785-4d49-93ea-bd31f2a187de.1667024922.8.1667271135.1667271037.'
}
编写对每一页请求的代码我们通过遍历来实现
num = int(input('请输入要爬取的页数:'))
for i in range(2,num+1):
url = f'https://kns.cnki.net/kns/brief/brief.aspx?curpage={i}'+abc
rsponse = requests.get(url, headers=head, cookies=cookie) #
print(rsponse.text)
这样就获得了每一页的数据,然后通过正则来实现筛选数据 #如果不懂可以去看我之前的文章
mc = re.findall(r'''target='_blank'>(.*?)</a>''', rsponse.text, re.S) #这是文章名称
zz = re.findall(r"""<td class='author_flag'>.*?target="knet">(.*?)</a>""", rsponse.text, re.S) #这是作者姓名
url_list = re.findall(r"""<a class="fz14" href='(.*?)' target='_blank'>""",rsponse.text,re.S) #这是文章的链接
#道理我都懂,可是把三个正则写一块实在是太慢了,分开写就可以了,离谱
然后把三列数据进行一一匹配,并写入txt里
for i in url_list:
urrll = 'https://kns.cnki.net/kcms/detail/detail.aspx?'+i
url_txt.append(urrll)
print(rsponse.text)
#print('这是名字',mc)
#print('这是作者',zz)
#print('这是链接', url_list)
a = list(zip(mc,zz,url_txt))
print(a)
for o in a:
with open('D:/python/爬虫练习库/自建练习/aa.txt',"a")as f:
f.write('\n'+str(o))
print('这是第'+str(num)+'页')
这个zip写的我真的服了,如果有更好的方法可以评论一下
#下面是源码
import requests
import re
head = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.26',
'Referer': 'https://kns.cnki.net/kns/brief/result.aspx'
}
# cookie = {
# 'Cookie':
# 'Ecp_ClientId=d221029142801567465; knsLeftGroupSelectItem=1%3B2%3B; Ecp_loginuserjf=urd1023@163.com; Ecp_ClientIp=43.242.155.3; RsPerPage=50; KNS_DisplayModel=listmode@CFLS; dsorder=download; ASP.NET_SessionId=4v2todmpqqfztxlrskewodns; SID_kns=126008; _pk_ref=%5B%22%22%2C%22%22%2C1667271037%2C%22https%3A%2F%2Fwww.cnki.net%2F%22%5D; _pk_ses=*; SID_kcms=025126024; SID_kns_new=kns25128005; SID_kinfo=126002; Ecp_IpLoginFail=22110143.242.155.24; SID_klogin=126002; KNS_SortType=; _pk_id=bbc9cfb9-d785-4d49-93ea-bd31f2a187de.1667024922.8.1667271135.1667271037.'
# }
num = int(input('请输入要爬取的页数:'))
abc = input('请输入链接后缀')
cooki = input('请输入cookie')
cookie = {
'cookie':cooki
}
for i in range(2,num+1):
url = f'https://kns.cnki.net/kns/brief/brief.aspx?curpage={i}'+abc
rsponse = requests.get(url, headers=head, cookies=cookie) #
#print(rsponse.text)
mc = re.findall(r'''target='_blank'>(.*?)</a>''', rsponse.text, re.S)
zz = re.findall(r"""<td class='author_flag'>.*?target="knet">(.*?)</a>""", rsponse.text, re.S)
url_list = re.findall(r"""<a class="fz14" href='(.*?)' target='_blank'>""",rsponse.text,re.S)
url_txt=[]
for i in url_list:
urrll = 'https://kns.cnki.net/kcms/detail/detail.aspx?'+i
url_txt.append(urrll)
print(rsponse.text)
#print('这是名字',mc)
#print('这是作者',zz)
#print('这是链接', url_list)
a = list(zip(mc,zz,url_txt))
print(a)
for o in a:
with open('D:/python/爬虫练习库/自建练习/aa.txt',"a")as f:
f.write('\n'+str(o))
print('这是第'+str(num)+'页')
#今天·还有·一篇