前言在早期网页开发体系与部分企业后台、政务系统、老旧管理平台中frameset多框架布局依旧被大规模沿用。区别于轻量化的 iframe 内联框架frameset 标签通过分割浏览器窗口将页面划分为多个独立、完整的 HTML 框架区域每个框架对应独立 URL、独立 DOM 文档与独立网络请求链路。常规爬虫仅能获取首页框架布局代码无法批量解析多框架分片数据存在数据碎片化、框架隔离、跨域限制、多页面同步抓取等一系列技术难题。相较于 iframe 局部嵌套特性frameset 属于页面级全局分割方案包含 frame 子标签、嵌套框架、左右分栏、上下分栏、混合分栏等复杂布局结构数据分散在不同框架单元内传统单页抓取方式完全失效。本文系统性讲解 frameset 页面底层架构、框架分割逻辑、静态批量抓取、动态框架渲染、多框架数据同步整合、嵌套 frameset 递归解析、反爬适配与数据统一结构化处理方案搭配完整可运行工程化代码、底层原理拆解、场景化案例与标准化数据整合方案补齐老旧架构网页爬虫开发核心短板。本次实战开发所需开源工具库及官方文档超链接如下全部支持 pip 快速部署便于开发者查阅原生 API 与版本适配文档1.requests轻量化 HTTP 请求库支撑静态框架页面高效请求2.BeautifulSoup4通用 HTML 解析器适配 frameset 老式页面语法3.lxml高性能 XML/HTML 解析引擎适配非标准老旧网页源码4.selenium浏览器自动化框架解决动态 frameset 渲染问题5.webdriver-manager驱动自动适配工具降低环境配置成本6.fake-useragent随机请求头生成组件规避基础访问拦截7.urllib3底层网络请求依赖库处理路径拼接与 URL 格式化全文基于 Python3.8 及以上稳定版本编写兼容 Windows、Linux、MacOS 全操作系统无闭源组件依赖纯开源技术栈实现多框架页面全覆盖抓取适配政务网站、老旧 OA 系统、工业后台、传统资讯站点等 frameset 架构场景。一、frameset 与 frame 核心架构原理1.1 frameset 基础定义与页面特性frameset 是 HTML 老式布局标签核心作用为替代 body 标签对浏览器可视区域进行横向、纵向混合切割每一个分割区域通过 frame 标签加载独立网页资源。该架构最大特征为页面无 body 主体整体由多个独立框架单元拼接而成各框架之间 DOM 隔离、请求独立、资源互不干扰。主流 frameset 布局语法示例html预览!-- 上下分栏框架布局 -- frameset rows100,* frame srctop.html nametopFrame frameset cols200,* frame srcleft.html nameleftFrame frame srcmain.html namemainFrame /frameset /frameset核心核心标签属性释义rows纵向分割比例实现上下分栏布局cols横向分割比例实现左右分栏布局frame框架最小单元承载单页面 URL 资源name框架唯一命名是爬虫定位与浏览器切换的核心标识noresize锁定框架尺寸仅为页面样式属性不影响数据抓取。1.2 frameset 与 iframe 核心差异对比多数开发者易混淆 frameset 与框架抓取逻辑二者底层架构与爬虫适配方案存在本质区别精准区分是多框架抓取的前提详细对比表格如下表格对比维度frameset 多框架iframe 内联框架页面层级全局页面分割替换 body 标签局部模块嵌套依附 body 存在布局形式整页分栏、多层嵌套分割局部内嵌弹窗、功能模块嵌入隔离等级完整文档级隔离独立窗口上下文局部 DOM 隔离共享主页面基础环境标签结构frameset 嵌套 frame多层级组合单一独立标签无嵌套强制要求抓取难点多页面分散、布局嵌套复杂单节点定位、动态 Src 生成适用场景老旧后台、政务系统、传统网站现代网页功能模块、第三方嵌入组件最优方案批量遍历 frame 标签 多请求整合单节点定位 上下文切换1.3 frameset 页面爬虫核心阻碍源码碎片化首页仅包含框架分割配置业务数据全部分散在数十个独立 frame 子页面嵌套层级复杂多层 frameset 嵌套组合横向纵向混合分割常规解析无法遍历全部框架路径适配困难老式页面大量使用相对路径、根路径直接提取 URL 易出现访问失效会话隔离问题部分后台系统框架共享 Cookie单独请求子框架会触发登录拦截动态框架生成部分改良版老旧系统通过 JS 动态渲染 frameset 结构静态解析无法获取 frame 链接。1.4 frameset 抓取技术方案选型结合框架静态程度、嵌套复杂度、权限校验机制划分三类标准化解决方案覆盖全部业务场景静态无嵌套 frameset采用 requestsBeautifulSoup 组合批量提取 frame 链接串行请求整合数据优势为轻量化、高并发、低资源消耗多层嵌套 frameset基于 lxml 递归解析标签树逐层遍历嵌套 frameset 内部 frame 节点实现全框架 URL 采集动态 JS 渲染 frameset依托 Selenium 浏览器渲染自动加载动态框架结构通过 frame 名称精准切换上下文抓取数据。二、frameset 抓取环境标准化配置2.1 依赖库批量安装指令针对 frameset 老旧网页语法兼容性安装适配老式 HTML 解析的全套依赖终端执行如下指令bash运行pip install requests beautifulsoup4 lxml fake-useragent selenium webdriver-manager2.2 编码与解析适配配置frameset 架构网站多搭建于早年服务器普遍存在 gb2312、gbk 编码格式区别于现代网站 utf-8 编码爬虫必须增加编码自动识别逻辑避免大面积中文乱码。同时关闭 HTML 严格校验适配老式不规范标签语法缺失问题。2.3 基础反爬基础配置老旧站点反爬机制较弱但普遍存在空 UA 拦截、Referer 来源校验统一配置随机请求头、来源伪造、超时重试机制保障多框架连续抓取稳定性。三、静态 frameset 页面批量抓取实战3.1 静态抓取核心实现原理纯静态 frameset 页面所有 frame 标签的 src 属性均为固定值无 JS 动态修改。核心执行逻辑分为三步第一请求 frameset 首页布局源码第二遍历全部 frame 标签批量提取子页面链接第三循环请求每一个框架页面独立解析数据最终完成多源数据合并与结构化存储。该方案无浏览器渲染开销请求吞吐量高适合大规模老旧资讯、公开政务类 frameset 网站抓取。3.2 单层 frameset 完整实战代码python运行import requests from bs4 import BeautifulSoup from fake_useragent import UserAgent from urllib.parse import urljoin class BaseFramesetSpider: def __init__(self): self.ua UserAgent() self.headers { User-Agent: self.ua.random, Referer: , Accept: text/html,*/* } self.timeout 20 self.all_frame_urls [] def get_frameset_html(self, main_url): 请求frameset首页布局源码 try: self.headers[Referer] main_url res requests.get(main_url, headersself.headers, timeoutself.timeout) res.encoding res.apparent_encoding return res.text, main_url except Exception as e: print(f首页请求失败{str(e)}) return None, main_url def extract_frame_url(self, html, base_url): 批量解析frame标签提取标准化链接 soup BeautifulSoup(html, html.parser) frame_list soup.find_all(frame) for frame in frame_list: src frame.get(src) if not src: continue full_url urljoin(base_url, src) self.all_frame_urls.append({ frame_name: frame.get(name, unknown), frame_url: full_url }) return self.all_frame_urls def crawl_frame_data(self, frame_url): 单独抓取单个框架页面数据 try: res requests.get(frame_url, headersself.headers, timeoutself.timeout) res.encoding res.apparent_encoding soup BeautifulSoup(res.text, html.parser) text_data soup.get_text(stripTrue, separator\n) return text_data except Exception as e: print(f框架页面抓取异常{frame_url}{e}) return def data_merge(self): 多框架数据统一整合封装 merge_result {} for item in self.all_frame_urls: content self.crawl_frame_data(item[frame_url]) merge_result[item[frame_name]] { url: item[frame_url], content: content } return merge_result if __name__ __main__: spider BaseFramesetSpider() target_url https://demo-frameset.example.com html, base spider.get_frameset_html(target_url) if html: spider.extract_frame_url(html, base) final_data spider.data_merge() print(多框架整合数据, final_data)3.3 代码逐段核心原理解析随机 UA 与 Referer 伪造老式服务器会校验请求来源将首页地址作为 Referer 传入模拟框架自然跳转逻辑规避 403 访问拒绝urljoin 路径拼接针对 frame 标签内相对路径、绝对路径、根路径三种书写格式自动补全完整 URL杜绝链接失效问题宽松 HTML 解析采用 html.parser 内置解析器忽略 frameset 页面不闭合标签、语法不规范等问题提升源码解析成功率分块数据存储以 frame 名称为键名存储对应框架内容保留数据来源标识便于后期数据拆分、筛选与二次处理全局异常捕获对单框架请求异常单独捕获单个框架失效不影响整体多页面抓取流程提升爬虫容错率。3.4 单层框架数据整合规范单层 frameset 多为上下、左右双栏或三栏布局数据整合建议采用字典结构化存储划分头部框架、侧边导航框架、主体内容框架三大模块区分导航文本、列表数据、正文内容避免多框架文本混杂无法区分。四、多层嵌套 frameset 递归解析方案4.1 嵌套框架抓取难点复杂企业后台系统普遍采用frameset 嵌套结构外层分割大区域内层二次细分布局常规单次 find_all 无法抓取深层嵌套 frame 标签会出现框架链接遗漏、数据缺失问题。必须基于 DOM 标签树深度遍历递归识别每一层 frameset 内部子节点。4.2 递归解析嵌套框架实战代码python运行from lxml import etree from urllib.parse import urljoin class RecursiveFramesetSpider(BaseFramesetSpider): def __init__(self): super().__init__() self.nested_frame_list [] def recursive_parse_frameset(self, html, base_url): 递归遍历嵌套frameset提取全部frame链接 tree etree.HTML(html) # 解析当前层级所有frame frame_nodes tree.xpath(//frame) for node in frame_nodes: src node.get(src) name node.get(name, nested_frame) if src: full_url urljoin(base_url, src) self.nested_frame_list.append({name:name,url:full_url}) # 递归查询下一层嵌套frameset frameset_nodes tree.xpath(//frameset) for fs in frameset_nodes: inner_html etree.tostring(fs, encodingutf-8).decode(utf-8) self.recursive_parse_frameset(inner_html, base_url) return self.nested_frame_list # 嵌套框架调用示例 if __name__ __main__: spider RecursiveFramesetSpider() url https://demo-nested-frameset.example.com html, base spider.get_frameset_html(url) if html: all_frames spider.recursive_parse_frameset(html, base) print(f累计抓取嵌套框架数量{len(all_frames)})4.3 递归解析底层原理lxml 树形遍历将 HTML 源码转为 XML 节点树通过 xpath 精准定位 frameset 与 frame 标签相比 BeautifulSoup 多层查询效率提升显著深度优先遍历从最外层框架开始逐层解析嵌套 frameset 节点将子 frameset 单独序列化后二次递归解析无层级限制全局集合存储所有层级框架链接统一存入全局列表自动去重防止嵌套重复抓取同一框架地址通用兼容逻辑不限制嵌套层数适配二级、三级及多级混合分栏框架布局覆盖复杂后台页面场景。五、动态 frameset 渲染抓取方案5.1 动态框架场景说明部分迭代升级的老式系统会通过 JavaScript 动态创建 frameset、frame 标签首页初始源码无任何框架节点静态请求无法获取子页面链接必须借助浏览器引擎完成 JS 渲染加载完整框架结构后再进行解析。5.2 Selenium 动态框架抓取代码python运行from selenium.webdriver import Chrome from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager class DynamicFramesetSpider: def __init__(self): opt ChromeOptions() opt.add_argument(--headlessnew) opt.add_argument(--no-sandbox) self.driver Chrome(serviceService(ChromeDriverManager().install()), optionsopt) self.wait WebDriverWait(self.driver, 15) def get_render_frames(self, url): self.driver.get(url) # 等待动态框架加载完成 self.wait.until(EC.presence_of_element_located((By.TAG_NAME, frameset))) # 获取所有渲染完成的frame元素 frame_elements self.driver.find_elements(By.TAG_NAME, frame) frame_info [] for frame in frame_elements: frame_info.append({ name: frame.get_attribute(name), src: frame.get_attribute(src) }) return frame_info def close(self): self.driver.quit() # 动态框架调用 if __name__ __main__: spider DynamicFramesetSpider() data spider.get_render_frames(https://demo-js-frameset.example.com) print(动态生成框架列表, data) spider.close()5.3 动态渲染核心逻辑拆解无头浏览器部署采用新版无头模式运行浏览器降低服务器资源占用适合后台无人值守爬虫部署元素等待机制通过显示等待监听 frameset 标签加载避免 JS 延迟加载导致的框架节点抓取为空渲染后属性提取直接读取浏览器渲染完成后的 src 与 name 属性完美适配 JS 动态修改框架地址的场景全量节点捕获浏览器会自动补全 JS 生成的全部 DOM 节点包含嵌套、动态生成的隐藏框架解析范围无死角。六、多框架数据整合与结构化处理6.1 多框架数据整合核心痛点frameset 页面数据分散、格式混乱、文本冗余度高单纯拼接所有框架文本会造成数据冗余、结构混乱无法直接用于数据分析、内容存储。标准化整合分为分类筛选、内容清洗、结构重组、统一存储四大步骤。6.2 多框架数据清洗规则空白过滤清除换行符、制表符、多余空格、页面占位符等无效字符模块划分根据 frame 名称区分导航栏、侧边栏、标题栏、正文内容分类存储重复剔除剔除多框架重复的公共导航文本、版权信息、底部通用内容格式统一统一换行分隔符规范文本排版提升数据可读性。6.3 多框架整合存储方案提供三种工程化存储方式适配不同业务需求JSON 结构化存储适合接口对接、二次开发保留框架分类字段本地 TXT 合并存储适合纯文本内容归档按框架名称分割区块数据库分字段存储适合大规模采集导航、正文、标题分栏入库。七、frameset 页面专属反爬突破策略7.1 老式框架站点常见限制同源访问限制frame 子页面校验上级页面来源非框架首页访问直接跳转拦截页会话绑定后台 frameset 系统所有框架共享 Session单独请求子页面强制跳转登录页链接时效限制部分管理系统 frame 链接携带临时参数脱离框架环境快速失效。7.2 针对性解决方案全局 Referer 绑定所有子框架请求统一携带首页 Referer模拟框架嵌套访问逻辑Cookie 全局同步使用 Selenium 登录后自动同步会话 Cookie 至所有框架请求保持登录状态全局会话对象采用 requests.Session 会话对象持久化保存 Cookie 与请求上下文适配需要登录的 frameset 后台完整上下文模拟动态抓取模式下不切换页面依托浏览器原生框架上下文绕过服务端同源校验。八、高频异常问题与解决方案汇总表格异常现象触发原因解决方案无法识别 frameset 标签网页为动态 JS 生成框架切换 Selenium 渲染模式等待 DOM 加载完成frame 链接 404 错误相对路径解析失败使用 urljoin 自动补全域名与路径子页面乱码严重老式页面 gbk/gb2312 编码启用 apparent_encoding 自动识别编码后台框架访问拒绝缺少登录会话使用 Session 维持 Cookie 或浏览器登录抓取嵌套框架数据缺失单层解析无法遍历深层启用递归解析方案深度遍历 frameset 节点九、全文总结frameset 作为老旧网页核心框架布局技术虽在现代前端开发中逐步淘汰但在政务平台、工业系统、企业老旧 OA、传统资讯站点中依旧广泛存在。区别于 iframe 局部抓取逻辑frameset 核心难点集中在多页面拆分、嵌套遍历、数据分散整合三大维度。本文通过静态单层抓取、递归嵌套解析、动态 JS 渲染三大核心方案完整覆盖所有 frameset 业务场景搭配可直接落地的工程化代码、底层原理拆解、数据整合方案与反爬适配策略形成标准化多框架爬虫开发流程。熟练掌握 frameset 抓取逻辑可有效解决特殊老旧架构网站的数据采集难题完善爬虫工程师全场景开发能力。