提取MLB网站MP4链接时,Python中json.loads无法将字符串转字典
问题分析与解决方法
你的问题出在这几个核心点上:
1. 硬编码索引提取内容完全不可靠
all_script_label[20]这种固定位置的提取方式完全依赖页面结构一成不变,MLB的页面随时可能调整script标签的顺序,你提取的内容大概率不是正确的目标数据块。
2. 提取的target不是标准JSON格式
MLB页面里的script内容是JavaScript对象,并非严格符合JSON规范:
- 可能用单引号代替双引号(JSON要求必须用双引号)
- 可能包含
undefined这类JSON不支持的关键字 - 末尾可能带分号或者其他多余字符
- 存在JS风格的转义或注释
这些都会直接导致json.loads和ast.literal_eval解析失败。
正确解决步骤
第一步:精准定位目标script标签
放弃固定索引,用正则匹配包含视频元数据的script块,比如找包含window.__INITIAL_STATE__或者mediaAsset的内容(MLB的视频数据通常存在这类全局变量里)。
第二步:将JS对象清理为标准JSON
把JS对象里不符合JSON规范的部分替换修正:
- 把单引号替换成双引号
- 把
undefined替换成null - 去掉末尾的分号
- 清理多余的空格或注释
第三步:解析JSON并提取MP4链接
示例代码
import requests import re import json from bs4 import BeautifulSoup url = "https://www.mlb.com/video/jeremy-pena-s-solo-homer?t=most-popular" content = requests.get(url).text # 匹配包含视频数据的全局变量script块 script_pattern = re.compile(r'window\.__INITIAL_STATE__\s*=\s*({.*?});', re.DOTALL) script_match = script_pattern.search(content) if script_match: # 提取JS对象字符串 js_obj_str = script_match.group(1) # 清理成标准JSON格式 cleaned_json_str = js_obj_str.replace("'", '"').replace("undefined", "null") # 解析JSON try: data = json.loads(cleaned_json_str) # 定位视频源(MLB视频链接通常在renditions列表中) media_renditions = data.get('videoPlayer', {}).get('mediaAsset', {}).get('playback', {}).get('renditions', []) # 筛选MP4格式的链接 mp4_links = [item['url'] for item in media_renditions if item.get('url', '').endswith('.mp4')] print("找到的MP4链接:") for link in mp4_links: print(link) except json.JSONDecodeError as e: print(f"解析失败:{e}") else: print("未找到目标视频数据块")
补充说明
- MLB的页面结构可能会更新,如果上面的正则匹配不到,可以打开页面F12查看Elements里的script标签,找到存储视频数据的全局变量名,调整正则即可。
- 部分视频可能有防盗链限制,直接访问MP4链接时可能需要携带请求头里的
Referer和User-Agent。
内容的提问来源于stack exchange,提问作者Gap
相关产品推荐
相关产品推荐

