news 2026/5/6 14:55:20

Python 爬虫进阶技巧:frameset 多框架页面数据整合抓取

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 爬虫进阶技巧:frameset 多框架页面数据整合抓取

前言

在早期网页开发体系与部分企业后台、政务系统、老旧管理平台中,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 rows="100,*"> <frame src="top.html" name="topFrame"> <frameset cols="200,*"> <frame src="left.html" name="leftFrame"> <frame src="main.html" name="mainFrame"> </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 页面爬虫核心阻碍

  1. 源码碎片化:首页仅包含框架分割配置,业务数据全部分散在数十个独立 frame 子页面;
  2. 嵌套层级复杂:多层 frameset 嵌套组合,横向纵向混合分割,常规解析无法遍历全部框架;
  3. 路径适配困难:老式页面大量使用相对路径、根路径,直接提取 URL 易出现访问失效;
  4. 会话隔离问题:部分后台系统框架共享 Cookie,单独请求子框架会触发登录拦截;
  5. 动态框架生成:部分改良版老旧系统通过 JS 动态渲染 frameset 结构,静态解析无法获取 frame 链接。

1.4 frameset 抓取技术方案选型

结合框架静态程度、嵌套复杂度、权限校验机制,划分三类标准化解决方案,覆盖全部业务场景:

  1. 静态无嵌套 frameset:采用 requests+BeautifulSoup 组合,批量提取 frame 链接,串行请求整合数据,优势为轻量化、高并发、低资源消耗;
  2. 多层嵌套 frameset:基于 lxml 递归解析标签树,逐层遍历嵌套 frameset 内部 frame 节点,实现全框架 URL 采集;
  3. 动态 JS 渲染 frameset:依托 Selenium 浏览器渲染,自动加载动态框架结构,通过 frame 名称精准切换上下文抓取数据。

二、frameset 抓取环境标准化配置

2.1 依赖库批量安装指令

针对 frameset 老旧网页语法兼容性,安装适配老式 HTML 解析的全套依赖,终端执行如下指令:

bash

运行

pip install requests beautifulsoup4 lxml fake-useragent selenium webdriver-manager

2.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, headers=self.headers, timeout=self.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, headers=self.headers, timeout=self.timeout) res.encoding = res.apparent_encoding soup = BeautifulSoup(res.text, "html.parser") text_data = soup.get_text(strip=True, 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 代码逐段核心原理解析

  1. 随机 UA 与 Referer 伪造:老式服务器会校验请求来源,将首页地址作为 Referer 传入,模拟框架自然跳转逻辑,规避 403 访问拒绝;
  2. urljoin 路径拼接:针对 frame 标签内相对路径、绝对路径、根路径三种书写格式,自动补全完整 URL,杜绝链接失效问题;
  3. 宽松 HTML 解析:采用 html.parser 内置解析器,忽略 frameset 页面不闭合标签、语法不规范等问题,提升源码解析成功率;
  4. 分块数据存储:以 frame 名称为键名存储对应框架内容,保留数据来源标识,便于后期数据拆分、筛选与二次处理;
  5. 全局异常捕获:对单框架请求异常单独捕获,单个框架失效不影响整体多页面抓取流程,提升爬虫容错率。

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, encoding="utf-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 递归解析底层原理

  1. lxml 树形遍历:将 HTML 源码转为 XML 节点树,通过 xpath 精准定位 frameset 与 frame 标签,相比 BeautifulSoup 多层查询效率提升显著;
  2. 深度优先遍历:从最外层框架开始,逐层解析嵌套 frameset 节点,将子 frameset 单独序列化后二次递归解析,无层级限制;
  3. 全局集合存储:所有层级框架链接统一存入全局列表,自动去重,防止嵌套重复抓取同一框架地址;
  4. 通用兼容逻辑:不限制嵌套层数,适配二级、三级及多级混合分栏框架布局,覆盖复杂后台页面场景。

五、动态 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("--headless=new") opt.add_argument("--no-sandbox") self.driver = Chrome(service=Service(ChromeDriverManager().install()), options=opt) 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 动态渲染核心逻辑拆解

  1. 无头浏览器部署:采用新版无头模式运行浏览器,降低服务器资源占用,适合后台无人值守爬虫部署;
  2. 元素等待机制:通过显示等待监听 frameset 标签加载,避免 JS 延迟加载导致的框架节点抓取为空;
  3. 渲染后属性提取:直接读取浏览器渲染完成后的 src 与 name 属性,完美适配 JS 动态修改框架地址的场景;
  4. 全量节点捕获:浏览器会自动补全 JS 生成的全部 DOM 节点,包含嵌套、动态生成的隐藏框架,解析范围无死角。

六、多框架数据整合与结构化处理

6.1 多框架数据整合核心痛点

frameset 页面数据分散、格式混乱、文本冗余度高,单纯拼接所有框架文本会造成数据冗余、结构混乱,无法直接用于数据分析、内容存储。标准化整合分为分类筛选、内容清洗、结构重组、统一存储四大步骤。

6.2 多框架数据清洗规则

  1. 空白过滤:清除换行符、制表符、多余空格、页面占位符等无效字符;
  2. 模块划分:根据 frame 名称区分导航栏、侧边栏、标题栏、正文内容,分类存储;
  3. 重复剔除:剔除多框架重复的公共导航文本、版权信息、底部通用内容;
  4. 格式统一:统一换行分隔符,规范文本排版,提升数据可读性。

6.3 多框架整合存储方案

提供三种工程化存储方式,适配不同业务需求:

  1. JSON 结构化存储:适合接口对接、二次开发,保留框架分类字段;
  2. 本地 TXT 合并存储:适合纯文本内容归档,按框架名称分割区块;
  3. 数据库分字段存储:适合大规模采集,导航、正文、标题分栏入库。

七、frameset 页面专属反爬突破策略

7.1 老式框架站点常见限制

  1. 同源访问限制:frame 子页面校验上级页面来源,非框架首页访问直接跳转拦截页;
  2. 会话绑定:后台 frameset 系统所有框架共享 Session,单独请求子页面强制跳转登录页;
  3. 链接时效限制:部分管理系统 frame 链接携带临时参数,脱离框架环境快速失效。

7.2 针对性解决方案

  1. 全局 Referer 绑定:所有子框架请求统一携带首页 Referer,模拟框架嵌套访问逻辑;
  2. Cookie 全局同步:使用 Selenium 登录后,自动同步会话 Cookie 至所有框架请求,保持登录状态;
  3. 全局会话对象:采用 requests.Session 会话对象,持久化保存 Cookie 与请求上下文,适配需要登录的 frameset 后台;
  4. 完整上下文模拟:动态抓取模式下不切换页面,依托浏览器原生框架上下文,绕过服务端同源校验。

八、高频异常问题与解决方案汇总

表格

异常现象触发原因解决方案
无法识别 frameset 标签网页为动态 JS 生成框架切换 Selenium 渲染模式,等待 DOM 加载完成
frame 链接 404 错误相对路径解析失败使用 urljoin 自动补全域名与路径
子页面乱码严重老式页面 gbk/gb2312 编码启用 apparent_encoding 自动识别编码
后台框架访问拒绝缺少登录会话使用 Session 维持 Cookie 或浏览器登录抓取
嵌套框架数据缺失单层解析无法遍历深层启用递归解析方案,深度遍历 frameset 节点

九、全文总结

frameset 作为老旧网页核心框架布局技术,虽在现代前端开发中逐步淘汰,但在政务平台、工业系统、企业老旧 OA、传统资讯站点中依旧广泛存在。区别于 iframe 局部抓取逻辑,frameset 核心难点集中在多页面拆分、嵌套遍历、数据分散整合三大维度。

本文通过静态单层抓取、递归嵌套解析、动态 JS 渲染三大核心方案,完整覆盖所有 frameset 业务场景,搭配可直接落地的工程化代码、底层原理拆解、数据整合方案与反爬适配策略,形成标准化多框架爬虫开发流程。熟练掌握 frameset 抓取逻辑,可有效解决特殊老旧架构网站的数据采集难题,完善爬虫工程师全场景开发能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/6 14:52:27

在 Simulink 中搭建出一个工业级的 PFC+LLC 级联电源仿真平台

目录 🎯 一、 核心目标与系统架构 系统整体架构图 🛠️ 二、 手把手建模步骤 第一步:前级 Boost PFC 建模与控制 第二步:后级 LLC 谐振变换器建模 第三步:级联系统的“痛点”优化——母线电容设计 第四步:联合仿真调试流程 📊 三、 仿真结果分析指南 💡 四…

作者头像 李华
网站建设 2026/5/6 14:49:29

如何永久保存微信聊天记录:WeChatMsg本地备份工具终极指南

如何永久保存微信聊天记录&#xff1a;WeChatMsg本地备份工具终极指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/W…

作者头像 李华
网站建设 2026/5/6 14:44:37

AMD迷你PC游戏性能优化:内存与操作系统影响解析

1. 迷你PC游戏性能测试&#xff1a;操作系统与内存的影响解析最近在折腾一台基于AMD平台的迷你PC时&#xff0c;我发现了一个有趣的现象&#xff1a;这台配置了16GB内存、运行Manjaro Linux的"伪Steam Deck"&#xff0c;在切换到Windows 11后性能明显下降。更奇怪的是…

作者头像 李华
网站建设 2026/5/6 14:42:41

AI视频生成系统优化实战:从显存爆炸到流畅输出

1. 项目背景与问题定位 去年夏天&#xff0c;我们团队接到了一个短视频平台的紧急需求——要在两周内开发出能够批量生成商品解说视频的AI系统。当时市面上刚开源的RealMaster模型看起来是个完美选择&#xff1a;论文里展示的生成效果流畅自然&#xff0c;架构设计也相当精巧。…

作者头像 李华