Python爬虫 | 2008-2018年各省专利统计数据

  • 目的及数据来源
  • 查询2008-2018年的专利统计年报
  • 获取2008-2018年专利统计年报的子页面的url地址
  • 获取2008-2018年专利统计年报的子页面的子页面的url地址
  • 结果示例
  • 总结


目的及数据来源

  1. 目的:获取2008-2018年各省专利申请状况、专利申请授权状况、专利有效状况、专利行政执法状况相关数据。
  2. 数据来源:知识产权局 https://www.cnipa.gov.cn/

查询2008-2018年的专利统计年报

以2018年为例,进入官方网站,选择 数据 — 统计报告查询 — 统计年报 — 选择2018年 — 点击查询 — 进入2018年专利统计年报汇编 — 前三项和最后一项就是我们要找的数据。

python 爬专利网站 专利数据爬虫_数据

  1. 2018年专利统计年报汇编:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/indexy.html
  2. 2017年专利统计年报汇编:https://www.cnipa.gov.cn/tjxx/jianbao/year2017/indexy.html

通过上述两个网址可以发现,2008-2018年的专利统计年报汇编url仅year后面的年份不同,其余均相同。因此,后续可通过for循环获取2008-2018年所有的目标网址。

获取2008-2018年专利统计年报的子页面的url地址

以2018年为例,获取2018年专利统计年报的子页面(专利申请状况、专利申请授权状况、专利有效状况、专利行政执法状况)的url地址:

  1. 专利申请状况:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/a.html
  2. 专利申请授权状况:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/b.html
  3. 专利有效状况:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/c.html
  4. 专利行政执法状况:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/h.html

通过上述子页面的url地址,可以发现这些地址都有相同的url开端:

https://www.cnipa.gov.cn/tjxx/jianbao/year2018/

也有相同的url结尾:

.html

只有代表不同子页面的部分不一致,分别为:

专利申请状况(a)、专利申请授权状况(b)、专利有效状况(c)和专利行政执法状况(h)

定义get_target_url函数,year为参数,获取该年份下所有的目标网址;再通过for循环获取2008至2018年所有的目标网址。

import requests
import pandas as pd
import os


# 获取各个页面的url(由于各个页面的url类似,可以考虑直接构建)
def get_target_url(year):
    url = 'https://www.cnipa.gov.cn/tjxx/jianbao/year' + year
    url_a = url + '/a.html'  #专利申请状况
    url_b = url + '/b.html'  #专利申请授权状况
    url_c = url + '/c.html'  #专利有效状况
    url_h = url + '/h.html'  #专利行政执法状况
    target_url = [url_a, url_b, url_c, url_h]
    return target_url


target_url = []
for year in range(2008, 2020):
    year = str(year)
    target_url = target_url + get_target_url(year)

获取2008-2018年专利统计年报的子页面的子页面的url地址

同样以2018年为例,获取专利申请状况、专利申请授权状况、专利有效状况、专利行政执法状况页面的所有子页面url地址:


(1) 链接1:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/a/a1.html

(2) 链接2:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/a/a2.html


(3) ……


(4) 链接18:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/a/a18.html

2.专利申请授权状况(b) (1) 链接1:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/b/b1.html

(2) 链接2:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/b/b2.html


(3) ……


(4) 链接14:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/b/b14.html

3.专利有效状况(c) (1) 链接1:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/c/c1.html

(2) 链接2:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/c/c2.html


(3) ……


(4) 链接9:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/c/c9.html

4.专利行政执法状况(h) (1) 链接1:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/h/h1.html

(2) 链接2:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/h/h2.html


(3) ……


(4) 链接6:https://www.cnipa.gov.cn/tjxx/jianbao/year2018/h/h6.html


通过上述子页面的url地址,可以发现这些地址也有一定的规律,后续只需要根据这些规律创建目标url即可。

定义save_to_excel函数,设置year和urls两个参数,根据目标网址爬取数据并存储到excel表格中,设置表格excel数据的保存地址为同目录文件夹;

定义get_table_url函数,设置year为参数,获取所有子页面的后部分url地址(如a/a1.html),结合save_to_excel函数将网页内容抓取保存为excel文件;再通过for循环结合get_table_url函数爬取网页内容。

代码中,try…except…部分是在自动化爬取过程中出现了bug,这个bug是由于2014/h/h2页面下的表格格式与其它表格不同所造成的,因此单独列出。

def save_to_excel(year, urls):
    times = 1
    for url in urls:
        header = {
            "User-Agent":
            "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
            "Cookie":
            "_trs_uv=kvxfw9lk_4693_1j0x; _va_ses=*; _va_id=1c99e31ff243ff58.1636785618.2.1636795627.1636785618."
        }
        req = requests.get(url, headers=header).text
        try:
            html_data = pd.read_html(req)[3]
        except:
            df = pd.read_html(req, header=0)[3]
            df_0 = pd.DataFrame([df.columns])
            df.columns = df_0.columns
            html_data = df_0.append(df, ignore_index=True)
        if times < 10:
            html_data.to_excel(
                r'D:\\YXH\\PythonLearning\\Python数据分析\\实验一\\国家知识产权局(2008及以后)专利统计数据\\'
                + year + '\\' + url[-7:-5] + '.xlsx')
            times = times + 1
        else:
            html_data.to_excel(
                r'D:\\YXH\\PythonLearning\\Python数据分析\\实验一\\国家知识产权局(2008及以后)专利统计数据\\'
                + year + '\\' + url[-8:-5] + '.xlsx')
            times = times + 1


def get_table_url(year):
    base_url = 'https://www.cnipa.gov.cn/tjxx/jianbao/year' + year
    urls_a = [base_url + '/a/a{}'.format(i) + '.html'
              for i in range(1, 19)]  #专利申请状况
    save_to_excel(year, urls_a)
    urls_b = [base_url + '/b/b{}'.format(i) + '.html'
              for i in range(1, 15)]  #专利申请授权状况
    save_to_excel(year, urls_b)
    urls_c = [base_url + '/c/c{}'.format(i) + '.html'
              for i in range(1, 10)]  #专利有效状况
    save_to_excel(year, urls_c)
    urls_h = [base_url + '/h/h{}'.format(i) + '.html'
              for i in range(1, 7)]  #专利行政执法状况
    save_to_excel(year, urls_h)


for year in range(2008, 2019):
    year = str(year)
    path = 'D:\\YXH\\PythonLearning\\Python数据分析\\实验一\\国家知识产权局(2008及以后)专利统计数据\\' + year
    isExists = os.path.exists(path)
    if not isExists:
        os.mkdir(path)
    get_table_url(year)

结果示例

  1. 2008-2018年专利统计年报
  2. 2008年专利统计年报
  3. 2008年a1文件

总结

本文调用了request、os实现爬取2008-2018年各省专利统计数据并存储到excel文件中,主要使用了pandas的read_html函数进行网页表格的解析。