jjzjj

[数据爬取】国家知识产权局(2008及以后)专利统计数据的收集(request+lxml+selenium)

终极白月光 2024-05-09 原文

【数据爬取】国家知识产权局(2008及以后)专利统计数据的收集(request+lxml+selenium)

前言

寒假里补数据分析课的实验报告,断断续续写了三四天,在这里记录下我稚嫩的代码。还有许多值得改进的地方,希望和大家互相学习。

任务要求

1、 百度搜索:国家知识产权局首页,打开以上链接

点击“数据”,找到“国家知识产权局统计年报”,输入年份,点击查询

2、 获取各年专利统计年报的子页面专利申请状况、专利申请授权状况、专利有效状况、专利行政执法状况的url。(提示由于url类似,可以考虑直接生成)

3、获取专利申请状况(专利申请授权状况、专利有效状况、专利行政执法状况做相同处理)子页面的所有url,

4、抓取对应页面的表格数据,并且输出到excel中

最终效果图

直接下载在了python文件目录

思路

一共有两种思路,第一种做着做着做不下去了,太笨太麻烦了;我最后用的是第二种

思路一

直接获取子url里每个表格的源码,用xpath解析表格里的数据,然后将数据整理写进excel中。

import requests
from lxml import etree
header1={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54'
}
page_text = requests.get(url='https://www.cnipa.gov.cn/tjxx/jianbao/year2018/a/a1.html', headers=header1).text
tree=etree.HTML(page_text)
title=tree.xpath('//body/table[2]/tr/td/b/span/text()')
tr_list=tree.xpath('/html/body/table[4]/tr')

for lines in range(len(tr_list)):
    a1line=get_a1line(lines,tr_list)
    print(a1line)

下面是整理之前的数据:

下面是整理所用的方法:(很笨)

def get_a1line(lines,tr_list):
    line = tr_list[lines].xpath('./td//text()')
    if lines==0:
        line0=['','','','','','']
        for j in [1,3,5,7]:
            line0.insert(j+1,line[j])
        return line0
    if lines==1:
        line1=['','']
        for j in [0,2,4,6,8,10,12,14]:
            line1.append(line[j])
        return line1
    if lines in (2,5,8):
        del line[1]
        del line[2]
        return line
    else:
        del line[1]
        line_new=['']
        line_new=line_new+line
        return line_new

而且后面还要用到合并表格的一系列麻烦操作,而且每个表格得重新写这个方法,总共有百八十个表格,我最终放弃了……

思路二

后面我观察表格页面,下面有一个下载按钮,点击可以直接下载excel表格,因此要做的就只是定位每个表格页面这个按钮,并将文件下载到指定位置就好!!主要就是用到了selenium.

下面是主程序

import requests
import os
from selenium import webdriver
from lxml import etree
from time import sleep
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options

#首先以年为单位,然后是四个类型,每个类型下有十多个表格
if __name__ == '__main__':
    header1 = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54'
    }
    for year in range(2009,2022):
        #新建目录
        mkdir(r'./十年情况/' + str(year))
        for index1 in ['a','b','c','h']:
            url1="https://www.cnipa.gov.cn/tjxx/jianbao/year{}/{}.html".format(year,index1)
            #获取每个子页面下的表格数量
            excel_number=get_excels(url1)
            #遍历
            for index2 in range(1,excel_number+1):
                #下载excel到指定位置
                download_excel(year, index1,index2)

下面是用到的一些方法

#新建文件夹
def mkdir(path):
    isExists = os.path.exists(path)
    # 判断结果
    if not isExists:
        # 如果不存在则创建目录
        # 创建目录操作函数
        os.makedirs(path)

#获取该页面下子url的数量(表格的数量)
def get_excels(url1):
    page_text = requests.get(url=url1, headers=header1).text
    tree = etree.HTML(page_text)
    tr_list = tree.xpath('/html/body/table[2]/tr')
    return len(tr_list)

下面这个方法是关键,有两个关键点,首先是启动参数的设置,然后就是观察下载按钮的xpath路径规律

def download_excel(year,index1,index2):
    #编写一个字典,方便文件夹命名,增加可读性
    dict = {'a': '专利申请受理状况',
            'b': '专利申请授权情况',
            'c': '专利有效状况',
            'h': '专利行政执法状况'
            }
    #设置启动参数
    options=Options()
    #启动参数列表:默认不加载图片;设置默认下载路径
    prefs = {"profile.managed_default_content_settings.images": 2,
             "download.default_directory": 'D:\pythonProject1\python数据分析\实验报告一\十年情况\{}\{}'.format(year,dict[index1])}
    options.add_experimental_option("prefs", prefs)
    #使用无头浏览器
    options.add_argument('--headless')
    #禁用GPU加速功能
    options.add_argument('--disable-gpu')
    # 实例化一个浏览器对象
    chrome_path = r"C:\Program Files\Google\Chrome\Application\chromedriver.exe"
    bro = webdriver.Chrome(executable_path=chrome_path,chrome_options=options)

    excel_url = "https://www.cnipa.gov.cn/tjxx/jianbao/year{}/{}/{}{}.html".format(year,index1,index1,index2)
    # 让浏览器发起一个网页请求
    bro.get(excel_url)

    #定位下载按钮
    # 获取每个表格里下载按钮所在的位置(行数)
    page_text = requests.get(url=excel_url, headers=header1).text
    tree = etree.HTML(page_text)
    table_list = tree.xpath('/html/body/table')
    cols=len(table_list)
    btn_download = bro.find_element(By.XPATH, r'/html/body/table[{}]/tbody/tr/td[2]'.format(cols))
    # /html/body/table[6]/tbody/tr/td[2]
    # /html/body/table[5]/tbody/tr/td[2]
    # /html/body/table[5]/tbody/tr/td[2]
    # /html/body/table[6]/tbody/tr/td[2]
    # /html/body/table[5]/tbody/tr/td[2]
    #/html/body/table[3]/tbody/tr/td[2]

    #点击下载按钮
    btn_download.click()
    sleep(3)

小结

这第二种思路和第一种比起来真的简便了许多,然后写的过程中自己也学到了很多,代码里需要改进的地方欢迎大家提意见,互相交流!

有关[数据爬取】国家知识产权局(2008及以后)专利统计数据的收集(request+lxml+selenium)的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  3. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  4. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  5. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  6. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  7. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  8. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  9. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  10. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

随机推荐