python + selenium实现巨潮资讯网指定范围年报下载

2023-10-31

大家好!第一次写文章,紧张滴捏!

  

这段时间在做课设,课设里需要下载沪市600000到601000号的年报原文做数字化关键词的词频分析,想着用程序帮我批量下载一下,但是找了一下貌似没有类似的代码,就写了一个应用selenium库来做模拟下载的python代码。

写的很烂,爬的很慢,稳定性也不太好,但总算还是爬出来了!下面先上代码,边看代码边讲解!

(注:使用这个方法要先安装selenium库与对应浏览器的驱动器哦!我这里下载的是Edge的驱动器)

首先是需要调用的各种python库~

#包含控制浏览器的类和方法
from selenium import webdriver

#用于执行复杂鼠标和键盘操作的类
from selenium.webdriver.common.action_chains import ActionChains

#用于添加延时或暂停
import time

#用于等待特定条件发生后再继续执行
from selenium.webdriver.support.ui import WebDriverWait

#定义用于等待的条件
from selenium.webdriver.support import expected_conditions as EC

#定义一组用于选择元素的方法
from selenium.webdriver.common.by import By

检测关键词的函数

下面,我写了一个用于判断可供选择的链接是年报还是年报摘要的函数。因为研究中需要的是年报,就把后文调用函数用到的关键词定为了“摘要”。

#定义一个check_world函数
def check_word(sentence, word):
    if word in sentence:  #如果关键词word在文本中,返回true,否则返回false
        return True
    else:
        return False

下载年报的函数

接下来就是用于自动化测试的函数啦!在这里,我定义了一个nianbao函数,当调用函数时,输入股票代码code,函数将会执行自动测试操作并下载网页。

def nianbao(code):

    # 启动Edge浏览器并加载选项
    browser = webdriver.Edge()
    url = 'http://www.cninfo.com.cn/new/commonUrl?url=disclosure/list/notice#sse'
    browser.get(url)
    browser.maximize_window()
    
    #输入时间
    #注:这段有没有都无所谓()因为我发现就算写了他也不会给我执行这段操作,但是因为网站的自动检索年报的范围就是我需要的范围,所以没差()
    browser.find_element_by_xpath('//*[@id="main"]/div[2]/div[1]/div[2]/div[1]/div[2]/form/div[1]/div/div/input[1]').send_keys('2022-12-31')
    browser.find_element_by_xpath('//*[@id="main"]/div[2]/div[1]/div[2]/div[1]/div[2]/form/div[1]/div/div/input[2]').send_keys('2022-06-15')
    #browser.find_element_by_xpath("//body").click()
    #browser.find_element_by_xpath("//body").click()
    
    
    #输入年报,将检索范围锁定在年报中
    #第一段用于点击分类按钮
    browser.find_element_by_xpath('//*[@id="main"]/div[2]/div[1]/div[2]/div[1]/div[2]/form/div[2]/div[3]/div/div/span/button').click()
    #第二段用于点击年报选项
    browser.find_element_by_xpath('/html/body/div[6]/div[1]/label[1]/span[1]/span').click()
    
    #输入代码
    #第一段用于点击输入框
    browser.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[1]/div[2]/div[1]/div[2]/form/div[2]/div[1]/div/div/div/div/input').send_keys(code)
    
    #这一段用于暂停页面操作,等待等待元素加载完成后继续执行操作(我设置的是三秒)
    time.sleep(3)
    
    #这一段用于点击搜索按钮,使用了更为稳健的模拟鼠标操作
    button_element = browser.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[1]/div[2]/div[1]/div[2]/div[1]/button')
    actions = ActionChains(browser)
    actions.move_to_element(button_element).click().perform()
    
    # 等待页面元素加载完成
    time.sleep(3)

    
    #进入公告
    #写了一个try,因为有时候可能对应的代码没有公司
    try:
        #调用check_word函数,判断要进入具体页面的报告是摘要还是年报
        word = "摘要"
        #获取页面中第二个xpath对应的text内容(如600000号股票就会返回“上海浦东发展银行股份有限公司2022年年度报告(全文)”)
        browser_text = browser.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[1]/div[1]/div[2]/div/div[3]/table/tbody/tr[2]/td[3]/div/span/a').text


        #如果是摘要,返回true,执行第一个xpath
        #注:有的页面可能有三个按钮,但是前两个按钮中一个有一个是年报或者年报修订版(确信)        
        if check_word(browser_text, word):
            browser.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[1]/div[1]/div[2]/div/div[3]/table/tbody/tr[1]/td[3]/div/span/a').click()

            #上一步操作后会打开一个新的页面,我们要获取新页面的url用于下载,将browser变更为新页面
            window_handles = browser.window_handles
            latest_window_handle = window_handles[-1]
            browser.switch_to.window(latest_window_handle)

        #当不含有摘要,返回false,点击第二个xpath
        else:
            browser.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[1]/div[1]/div[2]/div/div[3]/table/tbody/tr[2]/td[3]/div/span/a').click()
            window_handles = browser.window_handles
            latest_window_handle = window_handles[-1]
            browser.switch_to.window(latest_window_handle)        

        #获取网页url
        browser_url = browser.current_url

    #当所属公司code无法搜索出年报,那么这家公司可能是退市了,输出没有找到年报
    except Exception as e:
        print("没有找到",code,"的对应年报")
        browser.quit()
        
        #跳出方法
        return
        
    #这一段用于检测code有没有对应的公司,如果没有公司,那么点击搜索按钮只会停留在原来的页面上。这时执行上文获取的url就会下载错误的年报。
    #这里我用了暴力的解决方法,直接查看原有页面的前两个xpath具体页面的url内容,然后ban掉他们!这里在使用的时候一定要记得检查当日的前两位url
    if browser_url == "http://www.cninfo.com.cn/new/disclosure/detail?stockCode=688669&announcementId=1217087254&orgId=gfbj0833817&announcementTime=2023-06-17" or browser_url == "http://www.cninfo.com.cn/new/disclosure/detail?stockCode=603825&announcementId=1217085098&orgId=9900024448&announcementTime=2023-06-17":
        print("没有",code,"对应的公司")
        browser.quit()
    else: 
        browser2 = webdriver.Edge()
        browser2.get(browser_url)
        
        #进入url的页面,点击下载按钮,下载年报。其中,如果网不好+文件大的情况,就需要将time.sleep(10)的参数调大,不然下不完,网站就关了
        browser2.find_element_by_xpath('/html/body/div[1]/div/div[1]/div[3]/div[1]/button').click()
        time.sleep(10)
        print("已成功下载",code,"公司的年报")

        #关闭网站,防止资源浪费
        browser.quit()
        browser2.quit()
    

测试

写完函数,让我们调用它来测试一下:

code = "600000"
nianbao(code)

输出结果:

 在浏览器默认的下载路径中,已经出现了我们想要爬取的文件啦~

再来看看大批量调用的结果!毕竟我们写这个函数,最开始就是为了大面积自动下载文件嘛

for code in range(600301,601001):
    nianbao(code)

输出结果:

军火展示:

 

C盘内存告急(

当然,这种方法并不是一个批量下载文件的好方法。一方面,它会大量占用时间占用电脑()刚考了个六级又吃了个饭回来下了大概600份不到,如果遇到网不好的情况那更是痛苦,隔三差五就要检查有没有中途崩溃()

同时,xpath也很难搞,在写代码时经常会遇到使用xpath但点击不了元素的情况。如上文中,我本想直接进入年报链接来下载,但是那个页面的下载按钮无论如何都没法点击。我就参考了王宇韬老师的《Python金额大数据挖掘与分析全流程详解》中第十章的内容,选择获取连接重新打开一个页面来下载,用了这个方法才能够正常下载。

结语

在使用代码的时候,最好检查一下xpath和缩进有没有错误哦。

第一次用python做这种大批量的文件下载,还在不断地学习中。写的不太好,大家多多包涵,如果有更好的方法欢迎大家讨论分享!

下一篇大概会写Android Studio的B站视频数据爬虫或者自制的LaTeX数模论文模板(?)

谢谢大家收看(鞠躬)

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python + selenium实现巨潮资讯网指定范围年报下载 的相关文章

随机推荐

  • Docker安装初试&&制作centos6.5基础镜像

    https blog tankywoo com docker 2014 05 08 docker 4 summary html https yeasy gitbooks io docker practice content basic co
  • 五天自学完 王道考研-操作系统 第三章 段页式管理方式、虚拟内存

    第三章 基本分页存储管理的基本概念 如何实现地址的转换 页表 为了能知道进程的每个页面在内存中存放的位置 操作系统要为每个进程建立一张页表 基本地址变换机构 用于实现逻辑地址到物理地址转换的一组硬件机构 具有快表的地址变换机构 两级页表 基
  • 五大常用经典算法—分治算法

    原文作者 bigsai 原文地址 五大常用算法 一文搞懂分治算法 目录 前言 分治算法介绍 分治算法经典问题 二分搜索 快速排序 归并排序 逆序数 最大子序列和 最近点对 结语 前言 分治算法 divide and conquer 是五大常
  • 排名前10的vue前端UI框架值得你掌握

    最近在逛各大网站 论坛 SegmentFault等编程问答社区 发现Vue js异常火爆 重复性的提问和内容也很多 小编自己也趁着这个大前端的热潮 着手学习了一段时间的Vue js 目前用它正在做自己的公司项目 学习的过程之中发现继最热的
  • 记录--用js如何实现将手机号中间的几位数字变成****

    这里给大家分享我在网上总结出来的一些知识 希望对大家有所帮助 今天 我们要实现一个很常见并且简单的功能 将手机号中间的几位数变成 这个功能其实很常见 比如我们微信的账号安全里面显示的手机号 掘金的账号设置里面显示的手机号 支付宝里面的证件号
  • 安装 Protocol Buffer 2.5

    参考地址 https github com protocolbuffers protobuf releases tag v2 5 0 因 编译hadoop 源码 需要protocol 2 5 版本的环境 安装环境 windows10 1 下
  • 3DCAT携手华为,打造XR虚拟仿真实训实时云渲染解决方案

    2023年5月8日 9日 以 因聚而生 众志有为 为主题的 华为中国合作伙伴大会2023 在深圳国际会展中心隆重举行 本次大会汇聚了ICT产业界的广大新老伙伴朋友 共同探讨数字化转型的新机遇 共享数字化未来的新成果 华为中国合作伙伴大会20
  • 黑马Redis学习——实战篇(1)

    目录 1 短信登录 1 1 导入黑马点评项目 1 1 1 导入SQL 1 1 2 有关当前模型 1 1 3 导入后端项目 1 1 4 导入打开前端工程 1 2 基于Session实现登录流程 1 3 实现发送短信验证码功能 1 5 隐藏用户
  • 高中教学分析系统数据可视化探索【可视化实战案例】

    目录 前言 导入库 前言 教育行业中大数据分析的主要目的包括改善学生成绩 服务教务设计 优化学生服务等 而学生成绩中有一系列重要的信息往往被我们常规研究所忽视 通过大数据分析和可视化展示 挖掘重要信息 改善 学生服务 对于教学改进意义重大
  • Redis基本概念及配置(事务、持久化、主从复制、哨兵模式)

    Redis事务 Multi Exec discard 从输入Mulit命令开始 输入的命令都会进入命令队列中 但不会执行 直到输入Exec后 Redis将之前的队列中的命令依次执行 在命令组队过程中 可以使用discard放弃组队 如果某个
  • 无法找到元素 'aop:aspectj-autoproxy' 的声明

    通配符的匹配很全面 但无法找到元素 aop aspectj autoproxy 的声明 已解决 今天博主我在测试Spring Aop时遇到了一个在网上都很少见到的问题 是这样子的 当我执行Spring Aop测试代码时 它抛出了以下异常 o
  • 前端学习 C 语言 —— GDB调试器

    GDB调试器 我们在讲指针时用 GDB 调试段错误 本篇将详细介绍 gdb 的最常用命令 日志记录 检测点 最后介绍如何用 gdb 调试进程以及用gdb 调试一个开源项目的调试版本 glmark2 gdb介绍 GDB the GNU Pro
  • Android开发之RxJava使用

    RxJava是响应式编程 也可以理解为流式编程 核心是观察者模式 Rx是微软 Net的一个响应式扩展 Rx借助可观测的序列提供一种简单的方式来创建异步的 基于事件驱动的程序 2012年Netflix为了应对不断增长的业务需求开始将 NET
  • 华为OD机试 - 数字反转打印(Java)

    题目描述 小华是个对数字很敏感的小朋友 他觉得数字的不同排列方式有特殊美感 某天 小华突发奇想 如果数字多行排列 第一行1个数 第二行2个 第三行3个 即第n行有n个数字 并且奇数行正序排列 偶数行逆序排列 数字依次累加 这样排列的数字一定
  • AD9361配置采用纯PL方式,QT编写的小软件可以快速实现

    采用ADI官方的API函数 虽然能够快速的实现AD9361配置 让我们不必关注9361的内部寄存器的配置过程 但是在实际的项目开发过程中 也在一定程度上限制了AD9361与PL之间数据交互的灵活性 今天给大家推荐采用AD9361官方提供的配
  • Android开发之逐帧动画优化

    Android上如果使用逐帧动画的话 可以很方便地使用AnimationDrawable 无论是先声明xml还是直接代码里设置 都是几分钟的事 但使用AnimationDrawable有一个致命的弱点 那就是需要一次性加载所有图片到内存 万
  • go语言基础-----17-----channel创建、读写、安全关闭、多路复用select

    1 通道channel介绍 1 channel 可译为通道 是go语言协程goroutine之间的通信方式 2 channel通信可以想象成从管道的一头塞进数据 从另一头读取数据 通道作为容器是有限定大小的 满了就写不进去 空了就读不出来
  • 高防CDN对于网站、平台有着至关重要作用?

    1 减轻服务器的占用率和网站服务器的带宽资源 通过使用CDN服务 用户可以在CDN节点上分发对主要频道 包括页面和图片 的访问 这样可以减少源设备上的负载压力和带宽资源 并将资源保存到相同的带宽消耗服务中 如邮件 论坛和服务器资源 以保证网
  • 热区的使用方法

    1 如图所示 热区的位置是在元件库中 这样的一个标识 2 热区的使用经常会搭配一些比较小的文字或者图片等区域 只要是在热区中 随便点击哪一个地方都是属于这个区域 3 我们做了几个页面 样式不同 4 如图 我们创建一个热区在02的选区中 5
  • python + selenium实现巨潮资讯网指定范围年报下载

    大家好 第一次写文章 紧张滴捏 这段时间在做课设 课设里需要下载沪市600000到601000号的年报原文做数字化关键词的词频分析 想着用程序帮我批量下载一下 但是找了一下貌似没有类似的代码 就写了一个应用selenium库来做模拟下载的p