【第44期】Python 电影信息抓取:requests、JSON 清洗、限速和合规边界

发布时间:2026/9/25 18:38:23

【第44期】Python 电影信息抓取:requests、JSON 清洗、限速和合规边界 【第44期】Python 电影信息抓取requests、JSON 清洗、限速和合规边界CSDN 完整教程系列《从小白到 AI 大模型开发工程师的进阶之路》技术点AI-0132 网页电影信息抓取主人公小蓝伞前置AI-0128 requestsAI-0131 文件保存本期产出结构化数据文件第 40 期会发请求第 43 期会可靠落盘。小蓝伞想抓“电影信息”做练习第一反应是用 BeautifulSoup 去刮商业网站真正运行时搜索页偶尔返回登录 HTML代码却把它当 JSON最终生成了空的movies.json。这期先把边界钉死学习项目优先公开 API、开放数据或本地夹具没有授权就不解析商业页面。本期交付一个只采集最小字段的命令行程序以及可离线复现的成功、403、非 JSON、超时四类响应。真实外网状态随时会变所以网络步骤统一标为【建议验证】不能拿某次成功承诺长期可用。一、小蓝伞遇到的问题目标输入电影名得到标题、年份、摘要保存 UTF-8 JSON。风险无 timeout 的请求卡住把 HTML 当 JSON 解析没有 User-Agent 和间隔触发 429把有版权的海报和剧情大段转存到公开仓库建议插图 1公开 API、本地夹具、禁止的商业站点 HTML 三条路径。二、先给结论抓取首先是授权和契约问题其次才是解析问题。优先https://api.tvmaze.com/search/shows?q这类公开 JSON API或本地夹具。必须 timeout、检查状态码、校验结构。连续请求加间隔尊重 robots 和站点条款。只保存练习需要的字段不把整页 HTML 入库。网络失败时用本地样本保证测试不依赖外网。三、本文要解决什么项目内容输入电影/剧名字符串输出movies.json成功判据正常名返回列表空名失败非 JSON 失败超时可捕获不在范围登录绕过、验证码、大规模爬虫四、前置准备python-m pip install requests mkdir D:\ai-learning\issue-44不要提交 API Key。TVMaze 公开搜索不需要 Key仍要限速。五、核心原理一次请求至少有四层契约。传输层要求在超时时间内拿到响应HTTP 层要求状态码符合预期媒体层要求Content-Type是 JSON数据层要求顶层和字段结构正确。200只通过第二层网关完全可能用 200 返回 HTML 提示页。直接调用response.json()后捕获所有异常并返回[]会把“请求失败”伪装成“没有搜索结果”与上一期把坏 JSON 当空待办是同一类错误。清洗不等于删除所有标签。摘要字段可能为null、HTML 片段或超长文本应先校验类型再用标准解析器提取文本合并空白并限制长度。简单的.replace(p, )只能删固定标签遇到b、实体或属性会残留。本文使用标准库html.parser避免为了三个字段增加依赖复杂页面应在得到许可后选成熟解析库。限速也不是固定sleep(1)就万事大吉。单次命令只发一个请求批量调用需要由上层串行控制遇到 429 读取Retry-After或采用有上限的指数退避。不要换 IP、伪造 Cookie 或绕验证码。robots.txt由 RFC 9309 定义的是爬虫访问规则不是版权许可证即使规则允许也仍要阅读 API/站点条款并遵守数据用途限制。正确的数据流应是授权数据源 - timeout - 状态码 - Content-Type - JSON 结构 - 字段最小化 - 临时文件 - 原子替换 - 可离线复验六、完整项目目录结构issue-44/ ├── movie_fetcher.py └── fixtures/ └── search_ok.jsonfixtures/search_ok.json使用虚构数据避免把真实服务响应整包提交到仓库[{show:{name:Blue Umbrella Lab,premiered:2026-09-21,summary:pA bfictional/b learning sample./p}}]movie_fetcher.pyfromhtml.parserimportHTMLParserfrompathlibimportPathimportargparseimportjsonimportosimporttempfileimportrequests OUTPath(__file__).resolve().parent/movies.jsonAPIhttps://api.tvmaze.com/search/showsUA{User-Agent:ss-csdn-issue-44-learning/1.0,Accept:application/json}classTextExtractor(HTMLParser):从允许处理的摘要片段中提取纯文本。def__init__(self)-None:super().__init__()self.parts:list[str][]defhandle_data(self,data:str)-None:self.parts.append(data)defclean_summary(value:object)-str:ifnotisinstance(value,str):returnparserTextExtractor()parser.feed(value)return .join(.join(parser.parts).split())[:200]defnormalize(data:object)-list[dict]:校验响应结构只保留练习需要的三个字段。ifnotisinstance(data,list):raiseValueError(响应顶层必须是列表)rows[]foritemindata:showitem.get(show)ifisinstance(item,dict)elseNoneifnotisinstance(show,dict)ornotisinstance(show.get(name),str):continuerows.append({name:show[name].strip(),premiered:show.get(premiered),summary:clean_summary(show.get(summary)),})returnrowsdefsearch_show(name:str,session:requests.Session)-list[dict]:qname.strip()ifnotq:raiseValueError(名称不能为空)respsession.get(API,params{q:q},headersUA,timeout(3.05,10))resp.raise_for_status()content_typeresp.headers.get(Content-Type,).lower()ifjsonnotincontent_type:raiseValueError(f响应不是 JSON{content_typeor未知类型})returnnormalize(resp.json())defload_fixture(path:Path)-list[dict]:returnnormalize(json.loads(path.read_text(encodingutf-8)))defsave_rows(path:Path,rows:list[dict])-None:payloadjson.dumps(rows,ensure_asciiFalse,indent2)fd,temp_nametempfile.mkstemp(dirpath.parent,suffix.tmp)try:withos.fdopen(fd,w,encodingutf-8)asfile:file.write(payload)file.flush()os.fsync(file.fileno())os.replace(temp_name,path)exceptException:ifos.path.exists(temp_name):os.remove(temp_name)raisedefmain()-int:parserargparse.ArgumentParser()parser.add_argument(query,nargs?)parser.add_argument(--fixture,typePath)argsparser.parse_args()try:ifargs.fixture:rowsload_fixture(args.fixture)else:ifargs.queryisNone:raiseValueError(联网模式必须提供搜索词)withrequests.Session()assession:rowssearch_show(args.query,session)save_rows(OUT,rows)print(f保存{len(rows)}条到{OUT})return0except(OSError,ValueError,requests.RequestException,json.JSONDecodeError)asexc:print(f抓取失败{exc})return2if__name____main__:raiseSystemExit(main())先跑完全离线、结果固定的路径python movie_fetcher.py--fixture.\fixtures\search_ok.json python-m json.tool.\movies.json预期显示保存 1 条摘要为A fictional learning sample.文件里只出现三个目标字段。联网路径为python movie_fetcher.py Person of Interest【建议验证】。执行前重新查看 TVMaze API 条款与当前限制本文没有把 2026-09-21 某次响应当永久保证。七、可复现失败案例项目记录环节记录——构造方式假响应设置403、text/html正文为登录提示故障现象旧代码在json()报JSONDecodeError又被宽泛异常吞掉并保存[]影响权限失败被报成“无搜索结果”旧的有效文件还被空列表覆盖最初误判页面编码错误准备强制改成 UTF-8排查顺序状态码 - Content-Type - 响应前 200 字符 - JSON 顶层类型根因把 HTTP 成功、JSON 媒体类型和业务结构混成一个判断修复分层校验任何失败都不调用save_rows复验403、HTML 200、字典顶层分别失败原movies.json哈希保持不变失败样本只保存虚构片段真实响应可能包含账号、请求 ID 或网关信息不应直接贴到文章或公开仓库。八、实验设计与数据实验分离网络与解析。离线组固定夹具和假响应可在 CI 重复联网组只做手工连通性验证不作为测试必须通过的门槛。指标是退出码、保存条数、字段集合以及失败前后输出文件哈希。输入预期是否允许写文件合法列表夹具1 条、3 个字段、摘要无标签是空搜索词ValueError否200 text/html媒体类型错误否200 JSON 字典顶层结构错误否403 HTMLHTTP 错误否连接/读取超时RequestException否列表内缺少show.name跳过坏项并统计是这组实验能证明“失败不会伪装成空结果”不能证明远端 API 永久稳定也不能证明固定 10 秒适合所有网络。连接与读取使用不同 timeout是因为 DNS/TCP 建连慢和服务器响应慢是两类故障生产还应补重试预算、监控和缓存。九、常见问题与避坑为了消除证书错误设置verifyFalse。这会放弃服务端身份校验。应修复证书链或代理配置而不是隐藏风险。把 429 当普通失败立即重试。连续重试会加重限流。遵守Retry-After达到预算就停止。提交 Cookie、Token 或完整响应。它们可能包含凭证和个人信息。敏感配置放环境变量日志只留必要字段。选择器失效就不断加兼容分支。如果没有授权和稳定契约正确动作是停止并换公开数据源。摘要清洗只做字符串替换。标签和实体有多种形态应使用解析器并在输出侧限制字段长度。十、平台、系统与库的差异requests 是第三方库标准库 urllib 也能请求但异常、会话和超时接口不同不能直接复制代码。Windows 企业环境常有 HTTPS 代理或自签 CALinux 容器常缺代理配置云函数共享出口更容易触发限流。它们只改变部署与网络行为不改变四层校验。BeautifulSoup 只在处理自己或明确授权的 HTML 时使用。开发机、CI 和无网环境都应靠同一份离线夹具验证数据契约。十一、验证清单离线命令退出码为 0输出恰好 1 条字段集合只有name/premiered/summary。摘要中不应残留p、b长度不得超过 200 个字符。空搜索词、HTML 响应和字典顶层均返回退出码 2旧文件哈希不变。超时参数必须同时包含连接和读取上限代码中不得出现verifyFalse。仓库搜索不到 Cookie、Token、真实账号和整页 HTML。联网验证若执行要记录日期、数据源和结果失败只记“网络待复核”不能改写成 API 无效。批量扩展前先确认当前条款、频率限制与数据许可并把停止条件写进程序。让数据来源可以追溯只保存 name、premiered、summary 还缺一层工程信息这些字段从哪里来、何时取得、按哪个清洗版本生成。练习可在文件外维护 manifest记录 source、fetched_at、query、schema_version 和程序版本不要把完整响应或敏感请求头塞进去。某天摘要变化时读者能判断是远端更新、清洗规则变化还是同名条目匹配错误。没有来源元数据的数据即使格式整齐也很难复核。缓存与重试要遵守同一个授权边界。短时间重复查询可读取本地缓存减少对远端的压力缓存键至少包含标准化查询词和数据源版本缓存项要有过期策略。重试只适用于连接重置、部分 5xx 或明确允许的 429400、401、403 通常需要修正请求或权限自动重试没有意义。每次重试都应占用统一预算并带抖动避免多个进程同一时刻再次冲击服务。可观察性不要记录隐私。建议记录请求目标的主机、状态码、耗时、重试次数、返回条数和错误分类不记录 Cookie、Authorization、完整查询词或原始正文。错误正文若必须留作排查先截断、脱敏并限制访问教学项目最好只用虚构假响应。日志里的“0 条”必须区分为合法空列表与请求失败不能复用同一个成功事件。结构演进也需要门禁。远端新增字段不应导致失败因为本文只读取白名单关键字段类型改变、顶层从列表变字典则必须停止。可以用一小组离线契约样本覆盖最小合法项、含额外字段、summary 为 null、缺 name、顶层错误。每次改清洗器先跑这些样本再做一次手工联网验证。这样外网不可用时仍能开发外网恢复后又能检查真实契约是否漂移。不要把抓取速度当唯一指标。一个每秒一百请求却产生错误数据、违反条款、无法追溯的程序比每秒一个请求更差。验收顺序应是授权成立、失败可见、字段正确、写入可恢复最后才是吞吐。若业务确实需要大规模数据优先寻找批量下载、开放数据集或正式商业接口而不是把学习脚本加并发后直接运行。用假会话覆盖网络失败离线测试不必真的启动 HTTP 服务。定义一个 FakeResponse提供 status_code、headers、json 与 raise_for_statusFakeSession 的 get 记录 URL、参数、请求头和 timeout再返回预设响应或抛 requests.Timeout。这样可以断言代码确实传了(3.05, 10)Accept 为 JSON空查询甚至没有发起 get。假对象只模拟使用到的窄接口越小越容易看出测试和真实 requests 是否偏离。成功样本要验证清洗结果而不是只断言列表非空name 去掉首尾空白summary 去标签并合并空格null 变空串长度不超过 200。混入一个没有 name 的坏项后本文选择跳过更严格的业务可以整批拒绝或把坏项写入隔离区但必须统计跳过数。否则数据文件看似成功实际上每天悄悄少记录。失败样本要验证保存函数没有被调用。可以预先写入old文件令响应为 403、HTML、字典顶层或超时运行后比较原文件字节。若程序先清空输出再请求所有异常处理都来不及挽救旧数据。请求、规范化、保存三段函数分开正是为了让这个边界可以单独断言。真实联网验证只回答“此刻从这台机器能否按当前契约访问”。记录响应状态、媒体类型、条数和日期即可不把整包数据纳入测试快照。快照会迅速过期也可能重新分发不该保存的内容。远端失败时先检查 DNS、代理、证书、状态码和配额再判断是否是程序字段变化不要一看到 JSONDecodeError 就修改编码。如果以后增加分页循环必须有页数或记录数上限并在重复游标时停止。最后一页为空、next 缺失、游标循环是三种不同终止条件。未经验证的无限分页加自动重试会把小练习变成对远端持续施压的程序。合规边界必须落实为代码中的速率、预算和停止条件。保存前还应对记录做稳定排序或明确保留远端顺序否则同一批数据只因返回顺序变化就产生整文件 diff。若 name 不能唯一标识条目应保存数据源提供的稳定 ID用标题去重会把同名作品错误合并。本文为最小练习没有加入 ID 与分页扩展时应先修改输出 schema、夹具和迁移说明再增加请求数量。数据质量报告可以只包含四个数字收到条数、成功规范化条数、跳过条数、最终写入条数。四者关系不成立就拒绝保存。相比在日志里打印每条完整记录这组聚合既便于发现字段漂移也减少敏感内容暴露。错误率超过阈值时应停止而不是继续产出一份看似合法但大量缺行的 JSON。十二、面试题与追问为什么先 API 后 HTML契约稳定、授权清晰。追问HTML 永远不能用吗有书面授权或自己的页面可以。拿到 200 就成功了吗没有还要结构。追问和第 40 期关系同一条。429 怎么办降速、退避、停。追问换 IP 绕过学习项目禁止。如何让测试不依赖外网夹具和 fake session。追问那还要不要真实请求手工【建议验证】。保存 HTML 全文有什么问题版权、体积、结构不稳定。追问摘要截断到 200 字够吗练习够产品要看条款。十三、小蓝伞的工程金句抓取首先是授权问题其次才是解析问题。能离线测通的抓取才配进合集。200 只说明传输成功不说明数据可用。十四、本篇技术清单与下一期下一期AI-0133 简单计算器与数字游戏输入校验和随机数不碰网络。关注合集。你被 429 或 HTML 当 JSON 坑过吗先问能不能抓再问怎么抓。官方资料https://www.rfc-editor.org/rfc/rfc9309.htmlhttps://requests.readthedocs.io/en/latest/https://www.tvmaze.com/api适用边界学习与个人练习。商业数据以对方条款为准。
延伸阅读

更多相关文章

2026/9/25 18:33:23

IBM-供应链战略管理方法论:挑战与解决方案【附全文阅读】

这份 IBM 供应链战略咨询方案是大健康 / 保健品行业落地级标杆资料,实战参考价值突出。文档依托头部健康企业智能制造 4.0 专项项目,形成完整供应链诊断 + 变革落地全流程方法论,完全贴合多渠道、多 SKU、自有工厂 + 线下门店的复合业态特征。 方案先搭建标准化现状…

2026/9/25 18:33:23

EVE-NG v7嵌套虚拟化部署全栈指南

1. 这不是普通虚拟机安装,而是网络实验平台的底层基建EVE-NG v7 不是装个 Ubuntu 就能跑起来的玩具系统,它是一套为网络工程师、安全研究员和高校实验室量身打造的专业级网络仿真平台。我从 2018 年开始用 EVE-NG 做 Cisco、Juniper、Palo Alto 的拓扑验…

2026/9/25 18:33:23

101页进阶战略规划指南深度剖析Cross SWOT分析、市场洞察与内部能力优化的综合行动方案

适合企业董事长、总经理、高层经营管理者、战略总监;战略规划顾问、企业管理咨询师、产业研究人员;集团各业务单元、职能部门负责人,以及负责年度经营规划、市场布局、组织变革、数字化转型的管理者、战略落地操盘手和企管行政从业人员。 文档重要性总结 本 PPT 是一…

2026/9/25 19:33:26

python bool数据类型

bool数据类型的 bool 数据类型只拥有两个取值, 这两个取值分别是 True 以及 False, 它们的作用在于表示真意和假意, 同时也对应着对的概念和错的观念, 在这种类型通常会被放置于 if 语句环境之中的情形下, 程序会依据条件表达式的真假属性来选择具体的逻辑分支去向这个问题。本…

2026/9/25 19:33:26

Python自动化运维用什么编程语言

今天小编准备向大家分享一篇关于自动化运维过程中应该采用哪些编程语言的文章。对于运维工作方面,大家通常会比较熟悉这一点, 所以在通常情况下都会使用现有的常规方案去处理相关事务。不过我们需要弄清楚的问题是, 是否还有其他系统能够在极短的时间内高效地完成这些既定任务。…

2026/9/25 19:33:26

Ragent 会话记忆:最近 N 轮 + 持久化摘要如何平衡 Token 成本与上下文

Ragent 会话记忆:最近 N 轮 持久化摘要如何平衡 Token 成本与上下文 【免费下载链接】ragent 企业级 Agentic RAG 智能体 - 全链路覆盖文档解析、多路检索、意图识别、问题重写、会话记忆、MCP 工具调用与深度思考。面向真实业务场景,从 0 到 1 完整工程…

2026/9/25 19:28:26

Qt 常用控件实战:用 TaoToken 统一 Key 打通 QWidget 配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 20:24:47

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/25 0:02:35

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:02:35

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:02:35

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/25 18:41:36

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/25 18:34:56

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑