FEATURED · 精选文章

基于Selenium的金融数据自动化采集与反爬实战指南

发布时间 / 2026/9/3 17:12:21
来源 / 创域科博编辑部
栏目 / 资讯中心
基于Selenium的金融数据自动化采集与反爬实战指南 简介本资源是一套面向金融数据分析从业者、NLP研究者及量化初学者的实战型数据采集工具包聚焦解决上市公司财务数据自动化获取难、反爬机制强、data2text任务缺乏高质量结构化语料等核心痛点。压缩包共9个文件375KB含5个txt日志与配置文件如stocks.txt、failed_stocks.txt、1个核心Python爬虫脚本main.py、1个README.md说明文档、1个PNG示例数据图、1个DOCX附赠资料及1个TXT说明文件覆盖从环境配置、浏览器伪装、Cookie动态更新到异常处理的完整链路。已有55人学习下载适用于构建财报摘要生成、智能研报系统等data2text下游任务。用户可直接运行Selenium自动化脚本抓取同花顺财务报表复用预置的UA轮换、请求头伪造与浏览器行为模拟策略显著提升在强反爬场景下的采集稳定性与可持续性。1. 项目概述从数据采集到文本生成的金融数据管道最近在做一个金融领域的data2text项目简单来说就是让模型能读懂财务报表然后自动生成像分析师一样的解读报告。这个想法听起来很酷但第一步就卡住了数据从哪来我需要大量结构化的、干净的上市公司财务数据作为训练原料。市面上的数据API要么太贵要么字段不全要么更新不及时。于是目光自然就转向了同花顺这类财经门户网站它们的数据既免费又相对全面。但手动复制粘贴显然不现实这就引出了我们今天的主题如何构建一个稳定、可靠、能对抗网站反爬机制的自动化数据采集系统。这个项目的核心就是利用Selenium这个浏览器自动化工具模拟真实用户的操作从同花顺网站上将上市公司的三大报表资产负债表、利润表、现金流量表数据“抓”下来并经过清洗和格式化变成适合后续模型训练的规整数据集。整个过程听起来像是简单的“爬虫”但在金融数据这个场景下它远不止于此。你需要处理动态加载的JavaScript、应对频繁的登录验证和Cookie过期、伪装成正常用户访问以避免被封IP还要保证数据抓取的准确性和完整性。这更像是一个小型的“数据工程”项目每一步都充满了细节和陷阱。如果你也在为寻找特定领域的数据源发愁或者对如何用自动化工具高效获取网页数据感兴趣尤其是面对那些反爬措施比较严格的网站那么我在这趟“踩坑”之旅中总结的经验或许能帮你省下不少时间。接下来我会详细拆解整个系统的设计思路、关键技术的实现细节以及那些在文档里找不到的实战心得。2. 核心需求与方案选型为什么是Selenium在动手写代码之前明确需求和选择合适的工具至关重要。金融数据采集有其特殊性这直接决定了我们的技术方案。2.1 目标网站分析与核心挑战同花顺的财务数据页面例如某个公司的深度资料-F10-财务概况页面是典型的高度动态化的现代Web应用。数据并非直接写在HTML源码里而是通过JavaScript异步加载Ajax渲染到页面上的。这意味着如果你用传统的requests库直接去请求网页URL拿到的只是一个空的页面骨架看不到任何财务数字。主要挑战包括动态内容加载核心数据通过JS渲染简单HTTP请求无效。登录与会话维持查看详细财务数据通常需要登录账号且会话Cookie有有效期。反爬虫机制网站会检测异常访问行为如高频请求、无头浏览器特征、缺少正常用户交互等可能导致IP被暂时封锁或要求验证码。页面结构复杂数据分布在多个标签页Tab下需要模拟点击切换。数据格式化抓取到的数据是夹杂在HTML标签中的文本需要精确解析和清洗转换为结构化的CSV或JSON。2.2 工具选型Selenium的胜出面对这些挑战我们有几个备选方案Requests 逆向工程直接分析网站的数据接口XHR/Fetch模拟请求。这最高效但同花顺的接口可能经过加密、携带复杂令牌Token逆向难度大且接口一旦变动维护成本高。Playwright/Puppeteer新一代浏览器自动化工具比Selenium更现代API更优雅性能也更好。但对于这个项目其生态和资料量相对Selenium略少。Selenium老牌、稳定、生态极其丰富的浏览器自动化工具。它通过WebDriver直接控制Chrome、Firefox等真实浏览器能完美执行点击、输入、滚动等操作看到的就是用户看到的最终页面。我最终选择Selenium基于以下几点考量完美解决JS渲染问题Selenium驱动真实浏览器页面中的所有JavaScript都会被执行动态数据自然呈现我们直接对最终DOM进行操作即可。高度拟人化可以轻松模拟登录、点击标签页、滚动页面等所有用户行为极大地降低了被反爬系统识别为机器人的风险。强大的元素定位能力结合XPath、CSS Selector可以精准定位到页面中任何一个数据单元格。丰富的社区与资料任何你遇到的问题几乎都能在Stack Overflow或中文技术社区找到解决方案这对于快速开发和问题排查至关重要。灵活性虽然性能上不如直接调用接口但在应对复杂交互和反爬策略时其“以不变应万变”的能力非常突出。注意Selenium的速度相对较慢因为它要启动并渲染整个浏览器。如果对速度有极致要求且网站接口易于逆向requests方案更优。但对于同花顺这类防护严密的金融站点稳定性和成功率优先Selenium是更稳妥的选择。3. 系统设计与核心模块拆解整个数据采集系统可以看作一个管道Pipeline我将其分为五个核心模块如下图所示此处用文字描述逻辑流程[启动] - [浏览器驱动与伪装模块] - [登录与会话管理模块] - [数据导航与抓取模块] - [数据解析与存储模块] - [结束] | | | | |-- 反检测配置 |-- Cookie处理 |-- 页面元素遍历 |-- 文本清洗 |-- 用户代理(User-Agent)设置 |-- 自动更新/重登逻辑 |-- 多标签页/表切换逻辑 |-- 结构化存储(CSV/JSON)3.1 浏览器驱动与反爬伪装模块这是整个系统的基石。目标不仅是启动浏览器更是要让它“看起来”像一个真实的用户在操作。核心配置项无头模式(Headless Mode)选择开发调试时建议关闭无头模式headlessFalse这样你能看到浏览器的所有操作便于定位问题。在生产环境批量运行时可以开启节省资源。但要注意一些网站会检测无头模式。from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options Options() # 生产环境可开启 # chrome_options.add_argument(--headless) # 关闭“Chrome正受到自动测试软件控制”的提示栏这个提示栏可能被网站检测到 chrome_options.add_experimental_option(excludeSwitches, [enable-automation]) chrome_options.add_experimental_option(useAutomationExtension, False)用户代理(User-Agent)伪装使用最新的、常见的浏览器UA字符串避免使用Selenium默认的UA。chrome_options.add_argument(user-agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36)禁用WebDriver属性现代浏览器会暴露一个navigator.webdriver属性通常为true这很容易被检测。我们需要通过CDP命令将其覆盖。driver.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, { get: () undefined }); })其他实用参数# 禁用图片加载加速页面渲染如果不需要图片 # chrome_options.add_argument(--blink-settingsimagesEnabledfalse) # 禁用GPU加速避免一些兼容性问题 chrome_options.add_argument(--disable-gpu) # 设置窗口大小避免响应式布局导致元素定位失败 chrome_options.add_argument(--window-size1920,1080)实操心得反爬是一场攻防战。上述配置能绕过大部分基础检测但如果网站风控升级可能需要更复杂的策略如使用undetected-chromedriver这类专门对抗检测的库或者引入随机延迟、模拟鼠标移动轨迹等。3.2 登录与会话管理模块Cookie持久化与更新对于需要登录的网站管理会话是保证长期稳定运行的关键。我们不能每次运行脚本都手动登录。方案Cookie持久化首次手动登录保存Cookie在调试模式下运行脚本程序会暂停等待你手动在打开的浏览器窗口中完成登录包括可能的验证码。登录成功后将驱动器的Cookies保存到本地文件。import pickle import time def save_cookies(driver, path): # 等待登录完成比如通过判断某个登录后才会出现的元素 time.sleep(20) # 给你手动操作的时间 with open(path, wb) as file: pickle.dump(driver.get_cookies(), file) print(Cookies saved successfully.) # 首次运行后调用 # save_cookies(driver, 同花顺_cookies.pkl)后续运行加载Cookie再次运行脚本时先加载本地Cookies并添加到浏览器然后访问目标页面。如果Cookie有效则直接进入登录状态。def load_cookies(driver, path): try: with open(path, rb) as file: cookies pickle.load(file) for cookie in cookies: # 添加前可能需要删除expiry字段因为可能是浮点数导致错误 if expiry in cookie: # 处理过期时间或直接删除 del cookie[expiry] driver.add_cookie(cookie) print(Cookies loaded successfully.) return True except FileNotFoundError: print(Cookie file not found. Need manual login.) return False driver.get(https://www.10jqka.com.cn/) # 先访问域名 time.sleep(2) if load_cookies(driver, 同花顺_cookies.pkl): driver.refresh() # 刷新页面使Cookie生效 else: # 触发手动登录流程 input(请手动登录完成后按回车继续...) save_cookies(driver, 同花顺_cookies.pkl)Cookie失效处理Cookie会过期。我们需要在抓取数据前通过检查某个登录后特有的元素如用户昵称显示来判断当前是否仍处于登录状态。如果失效则提示需要重新手动登录并更新Cookie文件。重要提示Cookie包含敏感信息会话令牌。请勿将Cookie文件上传至公开的代码仓库如GitHub。务必将其添加到.gitignore文件中。3.3 数据导航与抓取模块这是业务逻辑的核心。我们需要编写代码来“指挥”浏览器找到目标公司页面并点击切换到正确的财务数据标签。步骤拆解定位公司页面通常我们有一个股票代码列表。同花顺的公司深度资料页有固定URL格式例如https://basic.10jqka.com.cn/股票代码/。直接拼接访问即可。等待页面加载使用Selenium的“显式等待”WebDriverWait这是最佳实践。它比固定的time.sleep更高效、更稳定。from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 访问公司页面 stock_code 000001 # 平安银行 driver.get(fhttps://basic.10jqka.com.cn/{stock_code}/) # 等待页面关键元素加载比如“财务概况”这个Tab try: finance_tab WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, //a[contains(text(), 财务概况)])) ) print(公司页面加载成功。) except TimeoutException: print(页面加载超时或元素未找到。)切换财务数据Tab找到“财务概况”、“资产负债表”、“利润表”、“现金流量表”等对应的链接或按钮并点击。finance_tab.click() time.sleep(2) # 等待Tab内容切换可以结合等待条件优化选择报告期财务数据通常有多个报告期如年报、季报。需要定位下拉框select并选择目标期数。from selenium.webdriver.support.ui import Select # 假设报告期下拉框的id是report_period period_select Select(driver.find_element(By.ID, report_period)) period_select.select_by_visible_text(2023年年报) # 根据文本选择 # 或者 select_by_value(20231231) time.sleep(3) # 等待数据重新加载实操心得页面元素定位是Selenium编程中最耗时也最容易出错的部分。强烈建议使用浏览器的开发者工具F12的“检查”功能结合Copy - Copy XPath或Copy selector来获取元素路径。但自动生成的XPath可能很脆弱例如包含变化的索引最好能自己编写更稳定的相对XPath或CSS选择器。3.4 数据解析与存储模块抓取到数据所在的HTML表格后我们需要将其“榨取”成结构化的数据。定位数据表格使用XPath或CSS选择器找到包含财务数据的table元素。# 假设数据在一个id为BalanceSheet的table里 table driver.find_element(By.ID, BalanceSheet)解析表格行与列遍历tr和td标签。data_rows [] for row in table.find_elements(By.TAG_NAME, tr): cols row.find_elements(By.TAG_NAME, td) if cols: # 跳过空行或表头行可能用th row_data [col.text.strip() for col in cols] data_rows.append(row_data)数据清洗处理空值和特殊字符将-、--转换为None或空字符串。格式化数字去除数字中的逗号如1,234.56、百分号5.6%并将其转换为浮点数或整数。注意处理单位如“亿元”。识别表头通常第一行或前几行是表头需要单独处理作为DataFrame的列名。结构化存储使用pandas库将数据列表转换为DataFrame然后保存为CSV或JSON文件。每个公司、每张报表最好单独存储并包含股票代码和报告期作为元数据。import pandas as pd df pd.DataFrame(data_rows[1:], columnsdata_rows[0]) # 假设第一行是表头 filename fdata/{stock_code}_资产负债表_2023年报.csv df.to_csv(filename, indexFalse, encodingutf-8-sig) # 用utf-8-sig避免Excel打开乱码4. 核心代码实现与关键步骤详解让我们将上述模块组合起来看一个抓取某公司资产负债表的核心代码片段。import pickle import time import pandas as pd from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait, Select from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException, NoSuchElementException class ThsFinancialCrawler: def __init__(self, cookie_pathths_cookies.pkl, headlessFalse): self.cookie_path cookie_path self.driver self._init_driver(headless) def _init_driver(self, headless): 初始化并伪装浏览器驱动 options webdriver.ChromeOptions() if headless: options.add_argument(--headless) options.add_argument(--disable-blink-featuresAutomationControlled) options.add_experimental_option(excludeSwitches, [enable-automation]) options.add_experimental_option(useAutomationExtension, False) options.add_argument(user-agentMozilla/5.0...) # 替换为你的UA driver webdriver.Chrome(optionsoptions) # 执行CDP命令隐藏webdriver属性 driver.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, { get: () undefined }); }) return driver def login_or_load_cookie(self): 登录或加载Cookie维持会话 self.driver.get(https://www.10jqka.com.cn/) time.sleep(3) try: with open(self.cookie_path, rb) as f: cookies pickle.load(f) for cookie in cookies: if expiry in cookie: del cookie[expiry] self.driver.add_cookie(cookie) print(Cookie加载成功刷新页面...) self.driver.refresh() time.sleep(3) # 验证登录是否成功 if self._check_login(): print(登录状态有效。) return True else: print(Cookie已失效。) raise Exception(Invalid Cookie) except (FileNotFoundError, Exception): print(需要手动登录。请在打开的浏览器窗口中完成登录。) input(登录完成后在此按回车键继续...) with open(self.cookie_path, wb) as f: pickle.dump(self.driver.get_cookies(), f) print(新Cookie已保存。) return True def _check_login(self): 检查是否处于登录状态例如查找用户昵称元素 try: # 这里需要替换为登录后页面实际存在的元素选择器 self.driver.find_element(By.CLASS_NAME, user-name) return True except NoSuchElementException: return False def crawl_balance_sheet(self, stock_code, report_year2023): 抓取指定股票代码、指定年份的资产负债表 url fhttps://basic.10jqka.com.cn/{stock_code}/ self.driver.get(url) print(f开始处理股票 {stock_code}...) try: # 1. 点击‘财务概况’或直接进入财务页面 # 这里XPath需要根据实际页面调整 finance_link WebDriverWait(self.driver, 15).until( EC.element_to_be_clickable((By.XPATH, //a[contains(href, /finance/) or contains(text(), 财务)])) ) finance_link.click() time.sleep(2) # 2. 切换到资产负债表Tab # 注意页面内可能有iframe需要先切换进去。这里假设没有或已处理。 balance_sheet_tab WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.XPATH, //*[contains(text(), 资产负债表)])) ) balance_sheet_tab.click() time.sleep(3) # 等待表格加载 # 3. 选择报告期 # 找到下拉框可能需要滚动到元素可见 select_element WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.XPATH, //select[idreport_date])) ) select Select(select_element) # 选择对应年份的年报这里逻辑需要根据下拉框选项调整 select.select_by_visible_text(f{report_year}年年报) time.sleep(4) # 重要等待数据异步加载完成 # 4. 定位并解析表格 table WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.XPATH, //table[classm-table]//tbody)) ) rows table.find_elements(By.TAG_NAME, tr) data [] for row in rows: cols row.find_elements(By.TAG_NAME, td) if cols: row_data [col.text for col in cols] data.append(row_data) # 5. 转换为DataFrame并保存 if data: # 假设第一行是表头项目期末余额期初余额... df pd.DataFrame(data) output_file f./data/{stock_code}_balance_sheet_{report_year}.csv df.to_csv(output_file, indexFalse, headerFalse, encodingutf-8-sig) print(f资产负债表数据已保存至 {output_file}) return df else: print(未找到表格数据。) return None except TimeoutException as e: print(f在抓取{stock_code}时发生超时错误: {e}) # 可以截图保存现场便于调试 self.driver.save_screenshot(ferror_{stock_code}.png) return None except Exception as e: print(f抓取{stock_code}时发生未知错误: {e}) return None def close(self): 关闭浏览器 self.driver.quit() # 使用示例 if __name__ __main__: crawler ThsFinancialCrawler(headlessFalse) # 调试时关闭无头模式 try: if crawler.login_or_load_cookie(): # 可以遍历股票代码列表 df crawler.crawl_balance_sheet(000001, 2023) print(df.head()) finally: crawler.close()关键步骤详解等待策略代码中混合使用了WebDriverWait显式等待和time.sleep固定等待。显式等待是首选它只在条件满足时才继续高效。但对于某些复杂的、非标准的Ajax加载有时不得不使用短暂的sleep来确保数据渲染完成。这需要根据目标网站的具体行为进行调整和测试。异常处理try...except块至关重要。网络不稳定、元素定位失败、页面结构微调都会导致程序崩溃。良好的异常处理能记录错误、跳过当前任务如当前股票继续执行下一个保证批量任务的完成度。页面结构变化同花顺前端的任何改版都可能导致XPath失效。因此定位器如XPath表达式应该尽可能使用相对路径和稳定的属性如id、name或包含特定文本内容避免使用绝对路径和易变的索引如div[3]/table[2]。5. 反爬策略进阶与实战避坑指南即使做了基础伪装在长时间、大批量抓取时仍然可能触发网站的反爬机制。以下是我在实践中总结的进阶策略和常见问题。5.1 高级反反爬策略请求频率控制这是最重要的原则。在循环抓取不同公司数据时在每次请求之间加入随机延迟模拟人类阅读和点击的间隔。import random import time def random_delay(min_sec2, max_sec5): delay random.uniform(min_sec, max_sec) time.sleep(delay) # 在抓取每个公司后调用 # random_delay(3, 8)IP代理池如果单个IP请求过于频繁被封就需要使用代理IP。可以购买付费代理服务或者使用一些免费的代理IP但稳定性差。在Selenium中设置代理chrome_options.add_argument(f--proxy-serverhttp://{proxy_ip}:{proxy_port})浏览器指纹多样化除了UA还可以随机化其他浏览器特征如屏幕分辨率、时区、语言等。这可以通过CDP命令或加载特定插件来实现但复杂度较高。使用undetected-chromedriver这是一个专门为绕过Cloudflare等高级反爬和浏览器指纹检测而修改的ChromeDriver。如果你的基础Selenium脚本被频繁拦截可以尝试换用它。import undetected_chromedriver as uc driver uc.Chrome()验证码处理如果遇到验证码最简单的策略是遇到就停。在代码中检测验证码页面的出现例如查找验证码图片元素一旦发现就记录下当前任务暂停程序等待人工干预解决后再继续运行。自动识别验证码OCR或打码平台成本高且不稳定对于个人项目不推荐。5.2 常见问题与排查技巧实录以下是我在开发过程中遇到的一些典型问题及解决方法整理成了速查表问题现象可能原因排查与解决思路NoSuchElementException元素找不到1. 页面未加载完成。2. XPath/CSS选择器写错了。3. 元素在iframe或shadow DOM内。4. 页面结构已更新。1. 增加等待时间使用WebDriverWait。2. 用浏览器开发者工具重新检查并验证选择器。3. 使用driver.switch_to.frame()切换到对应的iframe。4. 更新你的元素定位代码。ElementNotInteractableException元素不可交互1. 元素被遮挡如弹窗。2. 元素在视窗外需要滚动。3. 元素是disabled状态。1. 关闭遮挡物。2. 使用driver.execute_script(arguments[0].scrollIntoView();, element)滚动到元素可见。3. 等待元素变为可交互状态。页面加载慢或超时1. 网络问题。2. 网站服务器响应慢。3. 页面资源如图片、JS过多。1. 增加driver.implicitly_wait或WebDriverWait的超时时间。2. 在ChromeOptions中禁用图片加载(--blink-settingsimagesEnabledfalse)。3. 考虑使用代理。Cookie登录后很快失效1. Cookie生命周期短。2. 网站有额外的安全校验如IP绑定。3. 保存/加载Cookie的格式有问题。1. 定期如每天重新运行一次手动登录流程。2. 尝试保持IP地址相对固定。3. 检查pickle保存和加载过程确保expiry字段被正确处理。被网站识别为爬虫弹出验证码或拒绝访问反爬系统检测到自动化行为特征。1. 检查并完善浏览器伪装见3.1节。2. 大幅降低请求频率增加随机延迟。3. 更换User-Agent。4. 考虑使用undetected-chromedriver。5. 终极方案更换IP代理。抓取到的数据是空的或格式错乱1. 表格数据是异步加载的抓取时机过早。2. 定位到了错误的表格元素。3. 数字中包含非标准字符如全角空格、特殊单位。1. 在点击“选择报告期”后增加足够的等待时间或等待特定数据单元格出现。2. 打印出抓取到的HTML片段进行调试。3. 加强数据清洗逻辑使用正则表达式匹配和替换。独家避坑技巧多用try-except少用if在遍历元素如表格行时直接使用try-except包裹查找操作比先判断元素是否存在更简洁健壮。善用截图当脚本在无头模式下运行出错时你什么都看不到。在关键步骤后或异常捕获时使用driver.save_screenshot(debug.png)保存截图能极大帮助离线调试。分阶段测试不要一次性写完整个爬虫。先测试能否打开页面再测试能否登录然后测试能否找到某个按钮最后测试抓取一条数据。步步为营容易定位问题。尊重robots.txt在开始大规模抓取前检查目标网站的robots.txt文件如https://www.10jqka.com.cn/robots.txt了解网站允许和禁止爬取的目录。遵守规则是长期可持续抓取的前提。6. 数据预处理为data2text任务做准备抓取到的原始数据还不能直接喂给模型。对于data2text任务我们需要将结构化的表格数据转换成模型易于理解的“文本”格式。这个过程就是数据预处理。6.1 数据清洗与规整化合并多期数据我们通常需要多个报告期的数据如过去5年的年报。将抓取到的多个CSV文件每个文件代表一个公司一年的一张报表进行合并形成一个“宽表”每一行是一个公司-年份每一列是一个财务指标。import os import pandas as pd all_data [] for file in os.listdir(./data): if file.endswith(_balance_sheet_2023.csv): stock_code file.split(_)[0] df pd.read_csv(f./data/{file}, headerNone) # 假设无表头 # 这里需要复杂的逻辑来提取特定行如“流动资产合计”、“负债合计”并转置为列 # ... (具体解析逻辑取决于表格格式) # processed_series ... 得到一个Series索引是指标名值是指标值 # processed_series[股票代码] stock_code # processed_series[报告期] 2023 # all_data.append(processed_series) final_df pd.concat(all_data, axis1).T # 合并所有Series final_df.to_csv(combined_balance_sheet_2023.csv, indexFalse)处理缺失值与异常值某些公司可能缺少某些年份的数据或数据存在明显错误如负的资产。需要进行填充用前后年份均值或剔除。数据标准化不同公司的资产规模差异巨大。直接使用绝对值如“总资产1,000,000万元”不利于模型学习。通常需要进行标准化或归一化例如计算各个指标的同比增长率、占总资产的比例共同比报表等衍生指标。这些比率比绝对值更具可比性和信息量。6.2 构建模型输入文本data2text模型的输入通常是一段包含关键信息的“扁平化”文本。我们需要将规整好的结构化数据转换成自然语言描述。原始结构化数据示例股票代码: 000001 报告期: 2023 流动资产合计: 4,500,000 (万元) 非流动资产合计: 3,200,000 (万元) 资产总计: 7,700,000 (万元) 流动负债合计: 3,800,000 (万元) ...转换后的模型输入文本示例“平安银行(000001)2023年年报显示其总资产达到77000亿元较上年增长约10%。其中流动资产为45000亿元非流动资产为32000亿元。负债方面流动负债为38000亿元...”构建脚本的核心思路设计模板创建一个包含占位符的文本模板。template “{company_name}({stock_code}){report_year}年年报显示其总资产达到{total_assets}亿元较上年增长约{asset_growth_rate}%。其中流动资产为{current_assets}亿元非流动资产为{non_current_assets}亿元...”数据映射将DataFrame中的每一行数据填充到模板的对应占位符中。for idx, row in final_df.iterrows(): input_text template.format( company_namerow[公司名称], stock_coderow[股票代码], report_yearrow[报告期][:4], # 取年份 total_assetsrow[资产总计] / 10000, # 转换为亿元 asset_growth_raterow[资产同比增长率], # ... 填充其他字段 ) # 将input_text和对应的目标分析报告需要人工标注或从其他渠道获取配对存入训练集文件多样性可以设计多个不同侧重点的模板如侧重盈利能力、偿债能力、营运能力从同一份数据生成多条训练样本增加数据的多样性。这个预处理流程是data2text任务成败的关键之一。高质量、一致性好的输入文本能极大提升模型生成报告的可读性和准确性。整个从爬虫到预处理的管道搭建完毕后你就拥有了一个可持续生产训练数据的“武器库”为后续的模型训练打下了坚实的基础。本文还有配套的精品资源点击获取
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻