虽然写着第二天,但实际上离第二天过了不知道多久。具体的代码我前两天就写完和改完,但因为别的原因没写博客。
参考文献这个,实话说,很简单……毕竟只要找点规律就好。接下来该怎么绕过知网的反扒设计进行搜索才是重点,查了很多文章都没搞懂。
1. 需要的包
import requests
from lxml import etree
2. 用来作为测试的文章的url
# ▇▇▇▇▇ 00:参考文献所属文章的【url】▇▇▇▇▇
url="https://kns.cnki.net/KCMS/detail/detail.aspx?" \
"dbcode=CJFD&dbname=CJFD2014&" \
"filename=JJYJ201407004"

DJFD:《中国期刊全文数据库》
JJYJ:似乎是一个杂志的名字,后面的数字是发布时间。
3. 对url进行拆解,再组合,变成属于这个文章的参考文献的url
def get_reference_url(url):
# ▇▇▇▇▇ 01:获取url中重要的三个片段:decode、dbname、filename▇▇▇▇▇
a = url.split("?")
print(a)
d = []
for b in a:
c = b.split("&")
d.append(c)
print(d)
g = []
decode = str(d[1][0])
dbname = str(d[1][2])
filename = str(d[1][1])
# ▇▇▇▇▇ 02:利用三个片段组合成参考文献的目录▇▇▇▇▇
url_Reference = "https://kns.cnki.net/kcms/detail/frame/list.aspx?" \
+ decode + "&" + filename + "&" + dbname + "&RefType=1&vl="
print(url_Reference)
return url_Reference
参考文献的格式是确定的,和原文章的url有关,从开发者工具的Element里,找到参考文献所对应的代码里可以找到所需的url。
4. 获取参考文献网页
def get_page(url):
# ▇▇▇▇▇ 03:获取网页▇▇▇▇▇
headers = {
'Cookie': 'Ecp_ClientId=7191102150100801837; cnkiUserKey=d5f7f03f-22af-3775-8d3b-8a26cab33015; KNS_DisplayModel=listmode@CFLS; RsPerPage=50; KNS_SortType=CFLS%21%28FFD%252c%2527RANK%2527%29+desc; ASP.NET_SessionId=yc2srb0vatkcubu440fwcqaj; SID_kcms=124118; SID_krsnew=125134; _pk_ses=*; LID=WEEvREcwSlJHSldRa1FhdkJkVG5ha1U3OXdrbWpHSE1XcjZYdXYvZ0lZVT0=$9A4hF_YAuvQ5obgVAqNKPCYcEjKensW4IQMovwHtwkF4VYPoHbKxJw!!; SID_klogin=125143; c_m_LinID=LinID=WEEvREcwSlJHSldRa1FhdkJkVG5ha1U3OXdrbWpHSE1XcjZYdXYvZ0lZVT0=$9A4hF_YAuvQ5obgVAqNKPCYcEjKensW4IQMovwHtwkF4VYPoHbKxJw!!&ot=11/04/2019 15:36:27; c_m_expire=2019-11-04 15:36:27; Ecp_session=1; Ecp_LoginStuts=%7B%22IsAutoLogin%22%3Afalse%2C%22UserName%22%3A%22SH0184%22%2C%22ShowName%22%3A%22%25E5%25AE%2581%25E6%25B3%25A2%25E5%25B7%25A5%25E7%25A8%258B%25E5%25AD%25A6%25E9%2599%25A2%22%2C%22UserType%22%3A%22bk%22%2C%22r%22%3A%22ZU2XWU%22%7D',
'Host': 'kns.cnki.net',
'Refere': 'https://kns.cnki.net/KCMS/detail/detail.aspx?dbcode=CJFD&dbname=CJFD2014&filename=JJYJ201407004&uid=WEEvREcwSlJHSldRa1FhcTdWa2FjVHcvVGoxSUYvT2hQSk05Vmg0cStJZz0=$9A4hF_YAuvQ5obgVAqNKPCYcEjKensW4IQMovwHtwkF4VYPoHbKxJw!!&v=MDc0NTdJUjhlWDFMdXhZUzdEaDFUM3FUcldNMUZyQ1VSTE9lWnVadEZ5RGxWTHpQTHlmU1pMRzRIOVhNcUk5Rlk=',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'
}
# ==== requests:向网页请求数据 =================
response = requests.get(url=url, headers=headers)
html = response.text
parse = etree.HTML(html)
return parse
没什么好解释的》
5. 测试网页是否存在中文参考文献,没有就溜
def test_url(parse):
first_id = parse.xpath("//div[@class='essayBox'][1]//div[@class='dbTitle']/text()")
print(first_id)
if first_id[0] == "中国学术期刊网络出版总库":
return 0
else:
return 1
这是一个判断机制,其实是用来判断参考文献中是否还存在中文参考文献,如果没有,说明【7.】的循环结束了。
6. 获取标题/作者/作品所属文献/作品链接(感天动地,知网居然没有藏链接,哭了)
def get_Title(parse):
# ▇▇▇▇▇ 04:解析出参考文献【标题】列表▇▇▇▇▇
Reference_list = parse.xpath("//div[@class='essayBox'][1]//ul//a[1]/text()")
print(Reference_list)
return parse
def get_Author(parse):
# ▇▇▇▇▇ 05:解析出参考文献【作者】列表▇▇▇▇▇
Author_list_Bad = parse.xpath("//div[@class='essayBox'][1]//ul//li/text()")
Author_list = []
i = 0
for antuors in Author_list_Bad:
if i == 0:
i = i + 1
author = antuors.split(" ")
authr = author[1].split(".")
Author_list.append(authr[0])
else:
i = i - 1
print(Author_list)
return Author_list
def get_Periodical_list(parse):
# ▇▇▇▇▇ 06:解析出参考文献【所属刊物】列表▇▇▇▇▇
Periodical_list = parse.xpath("//div[@class='essayBox'][1]//ul//a[2]/text()")
print(Periodical_list)
return Periodical_list
def get_href(parse):
# ▇▇▇▇▇ 07:解析出参考文献【链接】列表▇▇▇▇▇
href_list_bad = parse.xpath("//div[@class='essayBox'][1]//ul//a[1]//@href")
href_list = []
for href in href_list_bad:
a = "https://kns.cnki.net"+href
href_list.append(a)
print(href_list)
return href_list
7. 测试是否存在参考文献下一页,知网的参考文献一页只有10个条目,万一有更多呢?
def get_Next_page(parse,url):
# ▇▇▇▇▇ 08:参考文献可能不止一页,利用一个循环测试是否存在第二页▇▇▇▇▇
page_info = parse.xpath("//div[@class='essayBox'][1]//div[@class='pageBar']//span/@id")
print(page_info)
# 利用【len()】判断是否存在第二页
if len(page_info):
page_num = parse.xpath("//div[@class='essayBox'][1]//div[@class='pageBar']"
"//span[@id=" + page_info[0] + "]/text()")
for i in range(2, 5):
next_page_url = url+"&CurDBCode=" + page_info[0] + "&page=" + str(i)
page = get_page(next_page_url)
if test_url(page) == 1:
break
else:
get_Title(page)
get_Author(page)
get_Periodical_list(page)
get_href(page)
else:
print("9")
本来想要直接读取页数。但是遇到了些问题……所以选择了利用链接的特点写了个循环,简单点。
8. 开搞!
url_Reference = get_reference_url(url)
page = get_page(url_Reference)
title = get_Title(page)
author = get_Author(page)
periodical = get_Periodical_list(page)
get_href(page)
get_Next_page(page,url_Reference)