基于Python的上市公司年报自动化抓取与OCR文本转换工具
2026/9/2 6:16:53 网站建设 项目流程

简介:这是一套面向金融数据分析从业者、量化研究者及财经专业学生的Python自动化工具集,专为解决巨潮资讯网上市公司年报PDF批量抓取与文本化难题而设计。工具链覆盖年报链接获取、PDF下载、OCR/文本提取及清洗转换全流程,显著降低词频分析、情感挖掘与关键词建模前的数据准备门槛。压缩包共13个文件(2.14MB),含4个核心Python脚本(链接抓取、PDF转码、文本分析等)、4个XML配置文件(支持IDEA环境适配)、1个Excel年报链接库(覆盖2004–2023年)、1个README说明文档及requirements.txt依赖清单,结构清晰、模块解耦,便于二次开发与参数调优。目前已有201人学习下载,使用者可直接运行脚本获取标准化TXT文本,结合Jieba、TF-IDF等工具开展年报主题建模、管理层语调分析或监管合规关键词筛查,具备强实用性与教学参考价值。

1. 项目缘起:从数据需求到自动化工具的诞生

在金融分析、学术研究或者投资决策的过程中,上市公司的年报是核心的数据来源。它不仅是公司经营状况的“体检报告”,更是洞察行业趋势、评估企业价值的关键文本。然而,直接从巨潮资讯网这类官方信息披露平台获取年报,并进行后续的文本分析,整个过程充满了琐碎和重复。你需要手动搜索公司、筛选年份、下载PDF、再想办法把PDF里的文字提取出来,最后才能进行词频统计或主题分析。这个过程做一两次尚可忍受,但如果需要分析几十家、上百家公司多年的数据,手动操作无异于一场噩梦。

这个项目的初衷,就是为了解决这个痛点。它不是一个复杂的金融数据平台,而是一个聚焦、高效的“流水线工人”。它的核心任务非常明确:自动从巨潮资讯网抓取指定上市公司的年报PDF,将其下载到本地,然后通过OCR(光学字符识别)技术将PDF内容转换为纯净的TXT文本。最终生成的TXT文件,可以直接被导入到任何文本分析工具(如Python的jiebasklearn,或者甚至简单的文本编辑器进行搜索)中,进行词频统计、情感分析、主题建模等操作。

我最初开发这个工具是为了自己的研究项目,在反复使用和优化中,积累了不少关于网络请求稳定性、反爬策略应对、PDF解析精度以及批量任务管理的经验。下面,我就把这个工具的完整实现思路、核心代码拆解以及那些“踩过坑才懂”的实操要点分享出来。无论你是金融专业的学生、量化分析的研究员,还是对Python爬虫和自动化感兴趣的朋友,这套方案都能为你提供一个坚实可靠的起点。

2. 工具核心架构与工作流程设计

在动手写代码之前,我们先从顶层设计上理解这个工具是如何运行的。一个健壮的工具不应该是一堆脚本的堆砌,而应该有一个清晰的逻辑脉络。我将整个流程分解为四个核心阶段,它们环环相扣,构成了工具的骨架。

2.1 阶段一:目标定位与请求构造

巨潮资讯网的数据查询主要依靠其公开的接口。我们的第一步,是模拟浏览器行为,构造出能够精确获取目标年报列表的HTTP请求。这里的关键在于理解巨潮网的查询参数。

通常,我们需要以下信息来定位一份年报:

  • 股票代码:如000001(平安银行)。
  • 公告类型:年报有固定的分类代码,例如年报通常对应category_ndbg_szsh(年度报告)等,但更可靠的方式是使用seDate(搜索日期)和stock组合查询。
  • 年份范围:通过seDate参数指定,例如2022-12-31~2023-12-31来获取2023年的年报。

一个典型的查询URL构造如下(以搜索平安银行2023年年报为例):

base_url = “http://www.cninfo.com.cn/new/hisAnnouncement/query” params = { ‘stock’: ‘000001,sz’, # 股票代码和交易所,sz代表深交所,sh代表上交所 ‘searchkey’: ‘年报’, ‘seDate’: ‘2023-01-01~2023-12-31’, ‘pageNum’: ‘1’, ‘pageSize’: ‘30’, ‘column’: ‘szse’, # 板块,深交所 }

向这个接口发送POST请求,会返回一个JSON格式的响应,里面包含了符合条件的公告列表,每条公告信息中就有我们梦寐以求的PDF下载链接(adjunctUrl字段)和公告标题(announcementTitle字段)。

注意:巨潮网的接口和参数可能会随时间微调。最稳妥的方式是打开浏览器开发者工具(F12),在“网络”(Network)选项卡中观察你在官网进行搜索时产生的真实请求,直接复制其中的参数。这是应对网站改动的第一手资料。

2.2 阶段二:PDF文件的智能下载与存储

拿到PDF下载链接后,事情并没有那么简单。巨潮网的PDF链接往往是相对路径,需要拼接上基础域名。此外,直接下载可能会遇到反爬机制,比如请求头校验。

这一阶段的核心任务是:

  1. 链接补全:将获取到的相对路径(如/new/disclosure/detail?stockCode=000001&announcementId=1214567890)拼接为完整URL(http://static.cninfo.com.cn/...)。具体规则需要从网站响应中分析。
  2. 模拟浏览器请求:为HTTP请求设置合理的User-AgentReferer等请求头,让我们的爬虫看起来更像一个正常的浏览器访问。
  3. 文件命名与存储:一份清晰的年报文件命名至关重要。我推荐的格式是:股票代码_年份_报告类型.pdf,例如000001_2023_年报.pdf。这样在本地管理成百上千个文件时会非常清晰。需要建立好对应的文件夹结构,比如按股票代码或年份分门别类存放。

2.3 阶段三:PDF到TXT的格式转换核心

这是技术挑战最大的一环。上市公司的年报PDF通常不是简单的“选中-复制”就能提取文字,它们往往是扫描件或者由图片构成,是“非文本型PDF”。对于这类文件,我们必须借助OCR技术。

我的方案是采用pdf2image+pytesseract的组合拳:

  1. PDF转图像:使用pdf2image库将PDF的每一页转换为高分辨率的PNG或JPEG图片。这里要注意设置DPI(每英寸点数),DPI越高,识别精度可能越好,但处理速度越慢,内存消耗越大。通常300 DPI是一个兼顾质量和效率的平衡点。
  2. OCR识别:使用pytesseract(它是Google Tesseract OCR引擎的Python封装)对每一张图片进行文字识别。Tesseract支持中文(chi_sim)和英文(eng)混合识别,这对于包含中英文的年报非常关键。
  3. 文本拼接与清洗:将每一页识别出的文本按顺序拼接起来。然后进行必要的清洗,比如去除过多的空白行、识别错误的特殊字符等,得到一份相对纯净的连续文本。

2.4 阶段四:批量处理与任务管理

单个公司的处理是基础,但我们通常需要批量处理。这就需要引入任务队列和简单的并发控制。

  • 任务队列:我们可以准备一个CSV文件或一个Python列表,里面记录了所有需要抓取的公司代码和年份对,例如[(‘000001’, ‘2023’), (‘600519’, ‘2023’), …]
  • 错误处理与重试:网络请求可能失败,OCR识别可能出错。代码中必须包含健壮的错误处理(try…except)和重试机制(如使用tenacity库)。对于失败的单个任务,应记录日志,方便后续手动补抓。
  • 进度可视化:在控制台输出当前进度(如“正在处理第X个任务,共Y个…”),对于长时间运行的批量任务,能极大提升用户体验和心理安慰。

整个工具的架构流程图可以概括为:输入任务列表 -> 循环处理每个任务 -> 查询公告 -> 下载PDF -> OCR转换 -> 保存TXT -> 记录日志。接下来,我们深入到代码层面,看看每一个环节具体如何实现。

3. 核心代码模块拆解与实现细节

理解了架构,我们来看具体的代码实现。我将核心功能封装成了几个函数,这样代码更清晰,也便于维护和复用。

3.1 环境准备与依赖库安装

工欲善其事,必先利其器。首先需要安装必要的Python库,此外,OCR引擎Tesseract需要单独安装。

Python库安装 (使用pip):

pip install requests lxml pandas pdf2image pillow pytesseract tenacity
  • requests: 用于发送HTTP请求,获取网页数据和PDF文件。
  • lxml/beautifulsoup4: 用于解析HTML(虽然巨潮主要用JSON接口,但备用解析有时需要)。
  • pandas: 方便地读取和管理任务列表(CSV文件)。
  • pdf2image: 将PDF转换为图像。
  • Pillow(PIL): 图像处理库,pdf2image的依赖。
  • pytesseract: OCR识别库。
  • tenacity: 提供优雅的重试装饰器,处理网络波动等临时性失败。

Tesseract OCR引擎安装:这是最关键的一步。pytesseract只是一个调用接口,真正的识别引擎是Tesseract。

  • Windows: 从 GitHub - tesseract-ocr/tesseract 下载安装程序。安装时记得勾选中文语言包(chi_sim)。安装完成后,需要将Tesseract的安装路径(如C:\Program Files\Tesseract-OCR)添加到系统环境变量PATH中,或者在代码中指定路径:pytesseract.pytesseract.tesseract_cmd = r‘C:\Program Files\Tesseract-OCR\tesseract.exe’
  • macOS: 使用Homebrew安装最为简单:brew install tesseract tesseract-lang。如果需要中文,可以安装brew install tesseract-lang或单独下载语言包。
  • Linux(如Ubuntu):sudo apt install tesseract-ocr tesseract-ocr-chi-sim

安装完成后,在命令行输入tesseract --version,确认安装成功,并查看是否支持中文。

3.2 公告查询与PDF链接提取模块

这个函数负责与巨潮网接口对话,获取目标年报的下载链接。

import requests import json import time from tenacity import retry, stop_after_attempt, wait_random @retry(stop=stop_after_attempt(3), wait=wait_random(min=1, max=3)) def fetch_announcement_list(stock_code, year, page_num=1): “”” 根据股票代码和年份,查询巨潮资讯网的年报公告列表。 返回一个列表,包含公告标题和PDF下载链接。 “”” # 构造查询参数 params = { ‘stock’: f‘{stock_code},sz’ if stock_code.startswith(‘0’, ‘3’) else f‘{stock_code},sh’, ‘searchkey’: ‘年报’, ‘seDate’: f‘{year}-01-01~{year}-12-31’, ‘pageNum’: str(page_num), ‘pageSize’: ’30’, ‘column’: ‘szse’ if stock_code.startswith(‘0’, ‘3’) else ‘sse’, } headers = { ‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36’, ‘Referer’: ‘http://www.cninfo.com.cn/new/commonUrl/pageOfSearch?url=disclosure/list/search’, ‘Content-Type’: ‘application/x-www-form-urlencoded; charset=UTF-8’, } base_url = ‘http://www.cninfo.com.cn/new/hisAnnouncement/query’ try: response = requests.post(base_url, data=params, headers=headers, timeout=10) response.raise_for_status() # 检查HTTP状态码 data = response.json() announcements = [] if data.get(‘announcements’): for ann in data[‘announcements’]: title = ann.get(‘announcementTitle’, ‘’) # 重点:提取PDF链接。adjunctUrl字段有时是完整URL,有时是相对路径。 pdf_url = ann.get(‘adjunctUrl’, ‘’) if pdf_url and pdf_url.endswith(‘.pdf’): # 如果是相对路径,需要补全 if pdf_url.startswith(‘/’): pdf_url = ‘http://static.cninfo.com.cn’ + pdf_url announcements.append({‘title’: title, ‘pdf_url’: pdf_url}) return announcements except requests.exceptions.RequestException as e: print(f“查询{stock_code} {year}年报列表失败: {e}”) return [] except json.JSONDecodeError as e: print(f“解析JSON响应失败: {e}”) return []

代码要点解析:

  1. @retry装饰器:来自tenacity库。它让函数在遇到异常时自动重试最多3次,每次重试前随机等待1-3秒。这对付不稳定的网络请求非常有效。
  2. 交易所判断:中国A股,代码以03开头的通常在深交所(szse),以6开头的通常在上交所(sse)。这个判断规则需要根据实际情况调整。
  3. 链接补全逻辑:这是根据对巨潮网静态资源域名观察得出的经验。如果adjunctUrl/开头,我们就为其拼接上http://static.cninfo.com.cn这个前缀。务必通过实际抓包验证这个规则是否仍然有效
  4. 错误处理:我们捕获了网络请求异常和JSON解析异常,并打印错误信息,避免因为单个请求失败导致整个程序崩溃。

3.3 PDF下载与本地存储模块

这个函数负责将网络上的PDF文件安全地下载到本地指定位置。

import os from urllib.parse import urlparse @retry(stop=stop_after_attempt(3), wait=wait_random(min=2, max=5)) def download_pdf(pdf_url, save_dir, stock_code, year): “”” 下载PDF文件到本地,并按照规则命名。 “”” # 创建保存目录(如果不存在) os.makedirs(save_dir, exist_ok=True) # 生成文件名:股票代码_年份_年报.pdf # 从URL中提取原始文件名作为备选,防止标题过长或含非法字符 parsed_url = urlparse(pdf_url) original_filename = os.path.basename(parsed_url.path) safe_filename = f“{stock_code}_{year}_年报.pdf” file_path = os.path.join(save_dir, safe_filename) # 如果文件已存在,跳过下载(避免重复工作) if os.path.exists(file_path): print(f“文件已存在,跳过下载: {file_path}”) return file_path headers = { ‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36’, } try: print(f“正在下载: {pdf_url}”) response = requests.get(pdf_url, headers=headers, stream=True, timeout=30) response.raise_for_status() with open(file_path, ‘wb’) as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) print(f“下载成功: {file_path}”) return file_path except requests.exceptions.RequestException as e: print(f“下载PDF失败 {pdf_url}: {e}”) # 可以选择删除可能已损坏的部分文件 if os.path.exists(file_path): os.remove(file_path) return None

实操心得:

  • stream=True:下载大文件时,使用流式传输可以避免一次性将整个文件加载到内存,更安全高效。
  • 文件存在检查:在批量处理时,这个检查能节省大量时间和流量。如果任务中途中断,重新运行时可以跳过已完成的文件。
  • 命名策略:使用股票代码_年份_报告类型.pdf的命名方式,在后续管理和查找时一目了然。避免使用公告标题直接命名,因为标题可能很长且包含特殊字符(如/,:等),导致保存失败。

3.4 PDF转TXT的OCR核心转换模块

这是整个工具的技术核心,直接决定了最终文本数据的质量。

from pdf2image import convert_from_path import pytesseract import tempfile import shutil def convert_pdf_to_txt(pdf_path, output_txt_path, dpi=300, lang=‘chi_sim+eng’): “”” 将PDF文件(尤其是扫描件)通过OCR转换为TXT文本文件。 “”” # 检查Tesseract命令是否可用 try: pytesseract.get_tesseract_version() except EnvironmentError: print(“Tesseract OCR未安装或未在PATH中,请正确安装并配置。”) return False # 创建一个临时目录来存放转换过程中的图片 with tempfile.TemporaryDirectory() as temp_dir: try: print(f“开始转换PDF: {pdf_path}”) # 1. PDF转图像 images = convert_from_path(pdf_path, dpi=dpi, output_folder=temp_dir, fmt=‘PNG’) print(f“PDF共{len(images)}页,已转换为图像。”) all_text = [] for i, image in enumerate(images): # 2. 对每一页图像进行OCR识别 # 可以在此处对image进行预处理,如灰度化、二值化、去噪等,以提高识别率 # image = image.convert(‘L’) # 转为灰度图 text = pytesseract.image_to_string(image, lang=lang) all_text.append(text) print(f“ 第{i+1}页识别完成。”) # 3. 将所有页的文本合并 full_text = ‘\n\n’.join(all_text) # 用两个换行符分隔不同页 # 4. 简单的文本清洗(可选,根据需求调整) # 移除过多的连续换行和空白字符 import re cleaned_text = re.sub(r‘\n\s*\n’, ‘\n\n’, full_text) # 将多个空行合并为一个空行 cleaned_text = re.sub(r‘[^\S\n]+’, ‘ ‘, cleaned_text) # 将多个空格合并为一个 # 5. 保存到TXT文件 with open(output_txt_path, ‘w’, encoding=‘utf-8’) as f: f.write(cleaned_text) print(f“TXT文件已保存: {output_txt_path}”) return True except Exception as e: print(f“转换PDF到TXT过程中发生错误: {e}”) return False

深度解析与调优建议:

  1. DPI的选择dpi=300是通用设置。对于字体较小、排版复杂的年报,可以尝试提高到400500,但处理时间和内存占用会显著增加。可以在小样本上测试,权衡精度和效率。
  2. 语言包lang=‘chi_sim+eng’表示同时使用简体中文和英文语言包进行识别。如果你的年报是纯中文,只使用chi_sim可能更快。确保你的Tesseract安装了对应的语言包。
  3. 图像预处理:OCR的精度很大程度上取决于输入图像的质量。pdf2image转换出的图像质量通常不错,但如果遇到识别率特别低的情况,可以在pytesseract.image_to_string之前加入预处理步骤:
    • image = image.convert(‘L’):转为灰度图,减少颜色干扰。
    • 使用PIL.ImageFilter进行锐化或模糊处理。
    • 使用pytesseract.image_to_dataimage_to_boxes获取更详细的识别结果进行后处理。
  4. 内存与性能:处理上百页的大型PDF时,convert_from_path一次性加载所有图像到内存可能导致内存不足。可以考虑使用convert_from_pathfirst_pagelast_page参数分批次处理,或者使用poppler的流式处理(更复杂)。
  5. 临时目录:使用tempfile.TemporaryDirectory()可以确保转换过程中产生的临时图像文件在函数结束后被自动清理,避免磁盘空间浪费。

3.5 主流程与批量任务调度

最后,我们将上述模块串联起来,并加入批量处理和日志功能。

import pandas as pd import logging from datetime import datetime def setup_logging(): “””配置日志,同时输出到控制台和文件。“”” log_filename = f“annual_report_crawler_{datetime.now().strftime(‘%Y%m%d_%H%M%S’)}.log” logging.basicConfig( level=logging.INFO, format=‘%(asctime)s - %(levelname)s - %(message)s’, handlers=[ logging.FileHandler(log_filename, encoding=‘utf-8’), logging.StreamHandler() ] ) return logging.getLogger(__name__) def main(): logger = setup_logging() # 1. 读取任务列表(例如从一个CSV文件) # CSV文件格式:stock_code,year task_file = ‘tasks.csv’ try: tasks_df = pd.read_csv(task_file) tasks = list(zip(tasks_df[‘stock_code’], tasks_df[‘year’])) except Exception as e: logger.error(f“读取任务文件{task_file}失败: {e}”) return # 2. 定义保存路径 base_pdf_dir = ‘./downloaded_pdfs’ base_txt_dir = ‘./converted_txts’ # 3. 遍历所有任务 for i, (stock_code, year) in enumerate(tasks, 1): stock_code = str(stock_code).zfill(6) # 确保股票代码是6位 year = str(year) logger.info(f“[{i}/{len(tasks)}] 开始处理 {stock_code} {year}年年报”) # 3.1 查询公告列表 announcements = fetch_announcement_list(stock_code, year) if not announcements: logger.warning(f“ 未找到{stock_code} {year}年的年报公告。”) continue # 通常第一份就是最新的年报,但也可以根据标题进一步筛选 target_announcement = announcements[0] # 取第一份 pdf_url = target_announcement[‘pdf_url’] # 3.2 下载PDF stock_pdf_dir = os.path.join(base_pdf_dir, stock_code) pdf_path = download_pdf(pdf_url, stock_pdf_dir, stock_code, year) if not pdf_path: logger.error(f“ 下载PDF失败,跳过后续转换。”) continue # 3.3 转换为TXT stock_txt_dir = os.path.join(base_txt_dir, stock_code) os.makedirs(stock_txt_dir, exist_ok=True) txt_filename = f“{stock_code}_{year}_年报.txt” txt_path = os.path.join(stock_txt_dir, txt_filename) success = convert_pdf_to_txt(pdf_path, txt_path) if success: logger.info(f“ 成功转换并保存TXT: {txt_path}”) else: logger.error(f“ PDF转TXT转换失败。”) # 3.4 礼貌性延迟,避免请求过快 time.sleep(1) logger.info(“所有任务处理完毕!”) if __name__ == ‘__main__’: main()

这个main函数构成了工具的指挥中心。它从tasks.csv读取任务,为每只股票创建独立的文件夹存放PDF和TXT,并记录了详细的处理日志。你可以通过修改tasks.csv文件轻松地扩展要抓取的公司和年份范围。

4. 实战中的“坑”与优化策略

纸上得来终觉浅,绝知此事要躬行。在大量实际使用中,我遇到了不少预料之外的问题,也总结出一些提升工具鲁棒性和效率的优化点。

4.1 反爬虫策略的应对之道

巨潮资讯网作为官方指定信息披露平台,对数据的公开性支持较好,但并非毫无限制。长时间、高频次的请求依然可能触发风控。

  • 症状:请求突然返回空数据、状态码非200、或者需要验证码。
  • 应对策略
    1. 降低请求频率:在每次网络请求后加入随机延迟(time.sleep(random.uniform(1, 3)))。这是最基本的礼貌,也能有效降低被封风险。
    2. 伪装请求头:确保User-Agent是真实的浏览器字符串,并携带Referer。可以准备一个User-Agent列表轮流使用。
    3. 使用IP代理池:对于超大规模的抓取(如抓取全市场十年数据),这是终极方案。需要购买或搭建代理IP服务,并在requests.get/post中通过proxies参数设置。免费代理不稳定,慎用
    4. 处理Cookie/Session:有些接口可能需要维持会话。可以使用requests.Session()对象来保持Cookie,模拟更真实的浏览行为。

4.2 OCR识别精度提升的实战技巧

OCR识别错误是影响后续文本分析质量的最大因素。年报排版复杂,包含表格、图表、特殊字体等,都会干扰识别。

  • 问题:数字“1”和字母“l”混淆,中文词语被错误分割,表格内容识别混乱。
  • 优化方案
    1. 区域识别:如果只关心年报中的“管理层讨论与分析”或“财务报告”部分,可以先用工具(如pdfplumbercamelot)尝试定位这些章节的页面坐标,然后只对特定区域的图像进行OCR,能大幅减少干扰和计算量。
    2. 自定义配置pytesseract.image_to_string可以传入config参数。例如,--psm 6(假设文本为统一的单行块)或--psm 3(全自动页面分割,但不进行方向检测)可能对某些版式更有效。需要通过实验找到最佳配置。
    3. 后处理校正:建立金融领域的自定义词典。例如,识别出的“公可”大概率是“公司”,“报生”可能是“报表”。可以用一个简单的映射字典进行替换。对于数字,可以结合上下文进行校验。
    4. 尝试更先进的OCR引擎:Tesseract是开源首选,但商业或云服务OCR(如百度OCR、阿里云OCR、Google Cloud Vision)的精度通常更高,特别是对复杂中文排版。它们通常提供免费额度,对于小规模或关键任务值得考虑,但需要处理API调用和费用。

4.3 大规模批量处理的稳定性保障

处理成千上万个任务时,程序运行几个小时甚至几天,稳定性至关重要。

  • 断点续传:我们的代码已经通过“检查文件是否存在”实现了简单的任务级断点续传。更完善的方案是将任务状态(待处理、处理中、成功、失败)记录在一个数据库(如SQLite)或状态文件中。程序启动时,先加载状态,只处理“待处理”和“失败”的任务。
  • 异常隔离:确保单个任务的失败不会导致整个程序崩溃。try…except要包裹每个任务的核心步骤,并将异常信息详细记录到日志中。
  • 资源监控:OCR转换非常消耗内存和CPU。在批量运行时,注意监控系统资源。可以考虑使用multiprocessingconcurrent.futures进行有限度的并发处理(例如同时处理2-3个PDF转换),但要注意线程/进程安全和资源竞争。
  • 日志为王:详细的日志文件是你排查问题的唯一依据。日志应记录时间、级别、股票代码、当前操作、成功或失败的信息、错误详情等。使用Python标准库的logging模块是最好的选择。

4.4 结果校验与质量评估

如何知道转换出的TXT文件质量是否合格?不能等到分析时才发现数据一团糟。

  • 自动化基础校验
    • 文件大小:转换后的TXT文件不应过小(比如只有几KB),这可能意味着OCR识别失败或PDF本身就是图片且质量极差。
    • 关键词抽查:编写一个简单的脚本,随机抽取一些TXT文件,搜索“营业收入”、“净利润”、“董事会”等年报中必然出现的高频关键词,检查是否能找到。
    • 段落长度统计:正常的文本段落长度分布有一定规律。如果发现文件充满了极短的行(可能是识别成了竖排文字或噪声),则质量可能有问题。
  • 人工抽样检查:定期随机打开几个生成的TXT文件,快速浏览一下。这是最直接有效的方法。

5. 从TXT到分析:词频分析快速入门

工具产出了干净的TXT文本,我们的最终目标——词频分析就可以轻松展开了。这里给出一个最基础的示例,使用jieba进行中文分词和词频统计。

import jieba from collections import Counter import os def analyze_word_frequency(txt_file_path, top_n=50): “”” 对单个TXT文件进行中文词频分析。 “”” try: with open(txt_file_path, ‘r’, encoding=‘utf-8’) as f: text = f.read() except FileNotFoundError: print(f“文件未找到: {txt_file_path}”) return # 使用jieba进行分词 words = jieba.lcut(text) # 移除停用词和短词(根据分析目标调整) stopwords = [‘的’, ‘了’, ‘在’, ‘是’, ‘我’, ‘有’, ‘和’, ‘就’, ‘不’, ‘人’, ‘都’, ‘一’, ‘一个’, ‘上’, ‘也’, ‘很’, ‘到’, ‘说’, ‘要’, ‘去’, ‘你’, ‘会’, ‘着’, ‘没有’, ‘看’, ‘好’, ‘自己’, ‘这’] # 可以加载更全的停用词表 filtered_words = [word for word in words if len(word) > 1 and word not in stopwords and word.strip()] # 统计词频 word_counts = Counter(filtered_words) # 输出前N个高频词 print(f“文件 ‘{os.path.basename(txt_file_path)}’ 词频分析结果 (Top {top_n}):”) for word, count in word_counts.most_common(top_n): print(f“ {word}: {count}”) # 可以返回结果用于进一步分析或可视化 return word_counts # 示例:分析刚转换好的一个文件 if __name__ == ‘__main__’: txt_path = ‘./converted_txts/000001/000001_2023_年报.txt’ result = analyze_word_frequency(txt_path, top_n=30)

你可以将这个函数嵌入到主流程中,在转换完成后立即进行分析,也可以批量处理所有生成的TXT文件,将结果汇总到一个DataFrame中,用于横向对比不同公司或不同年份的关注点变化。

这个工具链的价值在于,它将从数据获取到预处理再到初步分析的全流程自动化了。你可以在此基础上,轻松地集成更复杂的分析,如情感分析(使用snownlppaddlenlp)、主题模型(gensimLDA)、或构建自己的金融文本数据库。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询