虽然写着第二天,但实际上离第二天过了不知道多久。具体的代码我前两天就写完和改完,但因为别的原因没写博客。

参考文献这个,实话说,很简单……毕竟只要找点规律就好。接下来该怎么绕过知网的反扒设计进行搜索才是重点,查了很多文章都没搞懂。

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"


python爬虫知网一键下载_萌新

来源的文章如上图

 

 

 

 

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。

python爬虫知网一键下载_python爬虫知网一键下载_02

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)

其实这次还是很简单,但是要注意到网页里的链接和链接的特点才行。如果注释看不懂,不妨直接把代码复制到Python里运行下。