【爬虫实战】2.多线程批量下载+多线程PDF转TXT(另附2010-2021A股TXT年报下载)

2023-10-15 00:50

本文主要是介绍【爬虫实战】2.多线程批量下载+多线程PDF转TXT(另附2010-2021A股TXT年报下载),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.项目分析

数据来源:excel表格文件

项目需求:从excel表格中批量下载pdf版本的年报,将其命名为"股票代码_公司简称_ 年份"的格式,并全部转为txt文件。

使用语言:python

第三方库:pandas,requests, re , pdfplumber,time等。

实现思路:

  • 由于企业年报文件众多,需要加入多线程来改善程序运行速度;
  • 企业年报下载后体积较大,在转换为txt文件后清理原有pdf文件(可选);
  • 出于效率考虑,将下载与转换操作合并,读者亦可自行调整代码分离处理。

2. 具体步骤

1.准备工作

由于数据保存在excel文件中,所以第一步从读取数据入手,本文采用pandas库处理excel表格,其他第三库亦可。

import requests
import pandas as pd
import os
import multiprocessing
import pdfplumber
import logging
import relogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')# 读取Excel文件
try:df = pd.read_excel('年报_2015.xlsx')
except Exception as e:logging.error(f"读取失败!! {e}")return

下图为原始excel文件数据,我们可以用标题名称来作为查找名,并设置对应的变量。
在这里插入图片描述

# 读取文件内容并存储为字典
content_dict = ((row['公司代码'], row['公司简称'], row['年份'], row['年报链接']) for _, row in df.iterrows())
# 我们分别用code, name, year, pdf_url四个变量来接受这些值

在设置好变量后,还需要设置文件目录,用来存放下载的pdf文件和我们需要的txt文件,因此我们创建两个文件夹。

# 创建存储文件的文件夹
pdf_dir = 'pdf年报'
txt_dir = 'txt年报'
try:os.makedirs(pdf_dir, exist_ok=True)os.makedirs(txt_dir, exist_ok=True)
except Exception as e:logging.error(f"创建文件夹失败!请检查权限! {e}")return

2.多线程操作

前面提到,由于表格中的文件比较庞大,直接运行速度过于缓慢,需要加入多线程来提高效率,而且笔者将下载与转换都一次性处理,在分配一个线程进行,逻辑如下图所示。
在这里插入图片描述

多线程具体代码如下,我们开启一个线程池(网络上有很多人讲,这里不赘述),并加入了检查文件是否存在的功能,以防止程序意外中断后,会重复进行下载操作。

如果检测到文件不存在,则调用convert()函数进行下载和转换操作。

#开启多线程
with multiprocessing.Pool() as pool:for code, name, year, pdf_url in content_dict:txt_file_name = f"{code}_{name}_{year}.txt"txt_file_path = os.path.join(txt_dir, txt_file_name)#检测文件是否已经存在if os.path.exists(txt_file_path):logging.info(f"{txt_file_name} 已存在,跳过.")else:pool.apply_async(convert, args=(code, name, year, pdf_url, pdf_dir, txt_dir))pool.close()pool.join()

3.下载和转换

接下来的任务写好convert函数即可,这里这直接给出完整代码。

def convert(code, name, year, pdf_url, pdf_dir, txt_dir):pdf_file_path = os.path.join(pdf_dir, f"{code}_{name}_{year}.pdf")txt_file_path = os.path.join(txt_dir, re.sub(r'[\\/:*?"<>|]', '', f"{code}_{name}_{year}.txt"))try:# 下载PDF文件if not os.path.exists(pdf_file_path):with requests.get(pdf_url, stream=True) as r:r.raise_for_status()with open(pdf_file_path, 'wb') as f:for chunk in r.iter_content(chunk_size=8192):f.write(chunk)# 转换PDF文件为TXT文件with pdfplumber.open(pdf_file_path) as pdf:with open(txt_file_path, 'w', encoding='utf-8') as f:for page in pdf.pages:text = page.extract_text()f.write(text)logging.info(f"{txt_file_path} 已保存.")except Exception as e:logging.error(f"出错了- {code}_{name}_{year}. {e}")else:# 删除已转换的PDF文件,以节省空间os.remove(pdf_file_path)logging.info(f"{pdf_file_path} 已被删除。")

具体来说,第一步是根据输入参数构造出 pdf文件的完整路径和 txt文件的完整路径。这里使用了 Python 的 os.path.join 函数来拼接文件路径,以及 re.sub 函数来去除文件名中的非法字符。

接下来就是用 requests 库从 pdf_url 下载文件,并将其保存在 pdf_file_path 中。下载的过程中,函数会以 8192 字节为一块,依次将文件块写入本地文件。

如果 pdf文件下载成功,我们使用 pdfplumber 库将 其转换为txt文件。

最后,函数会删除已经转换成功的 pdf文件,这样就大功告成了~


3.成果展示

经过整理,得到了如下txt文本,可以看到txt文本内容与原内容一致,便于我们之后进行词频分析。
在这里插入图片描述
在这里插入图片描述

文本挖掘是财经类学术研究的常用方式,特别是借助上市公司年报进行词频分析的应用十分广泛。
若要获取完整代码文件,或者2010-2021的txt年报下载链接,可以关注同名公众号“凌小添”回复‘年报’获取哦~

这篇关于【爬虫实战】2.多线程批量下载+多线程PDF转TXT(另附2010-2021A股TXT年报下载)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/214274

相关文章

Python实现Word转PDF全攻略(从入门到实战)

《Python实现Word转PDF全攻略(从入门到实战)》在数字化办公场景中,Word文档的跨平台兼容性始终是个难题,而PDF格式凭借所见即所得的特性,已成为文档分发和归档的标准格式,下面小编就来和大... 目录一、为什么需要python处理Word转PDF?二、主流转换方案对比三、五套实战方案详解方案1:

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

Nginx进行平滑升级的实战指南(不中断服务版本更新)

《Nginx进行平滑升级的实战指南(不中断服务版本更新)》Nginx的平滑升级(也称为热升级)是一种在不停止服务的情况下更新Nginx版本或添加模块的方法,这种升级方式确保了服务的高可用性,避免了因升... 目录一.下载并编译新版Nginx1.下载解压2.编译二.替换可执行文件,并平滑升级1.替换可执行文件

shell脚本批量导出redis key-value方式

《shell脚本批量导出rediskey-value方式》为避免keys全量扫描导致Redis卡顿,可先通过dump.rdb备份文件在本地恢复,再使用scan命令渐进导出key-value,通过CN... 目录1 背景2 详细步骤2.1 本地docker启动Redis2.2 shell批量导出脚本3 附录总

批量导入txt数据到的redis过程

《批量导入txt数据到的redis过程》用户通过将Redis命令逐行写入txt文件,利用管道模式运行客户端,成功执行批量删除以Product*匹配的Key操作,提高了数据清理效率... 目录批量导入txt数据到Redisjs把redis命令按一条 一行写到txt中管道命令运行redis客户端成功了批量删除k

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多