如何从网页提取JSON数据并筛选指定字段输出结构化结果
问题根因
你之前的代码无法拿到数据的核心原因有两个:
- 你请求的是Gitiles代码托管平台的网页展示地址,返回的是经过语法高亮渲染的HTML页面,页面DOM里不存在你XPath匹配的
class="operators"节点,自然提取不到内容 - 针对本身就是JSON格式的公开数据源,解析HTML提取内容属于冗余操作,平台本身提供了直接获取原始文件的接口,稳定性和实现难度都远优于DOM解析方案
实现方案
目标JSON文件本身的结构和你需要的输出格式几乎完全一致,只需要拿到原始文件内容剔除冗余字段即可,不需要用到lxml库:
- 在目标文件URL末尾拼接
?format=TEXT参数,接口会返回Base64编码的原始JSON内容 - 解码Base64内容得到标准JSON结构,顶层
operators数组就是所有运营商列表 - 遍历每个运营商节点,保留
name字段;再遍历每个运营商下的logs数组,每个日志只保留description和log_id两个字段,其余字段全部剔除 - 整理后的结构直接序列化为格式化JSON即可
完整可运行代码
import requests import base64 import json # 目标文件地址,拼接参数获取原始base64内容 target_url = "https://chromium.googlesource.com/chromium/src/+/main/components/certificate_transparency/data/log_list.json?format=TEXT" # 携带常规浏览器UA避免被接口拦截 req_headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" } # 发起请求 response = requests.get(target_url, headers=req_headers) response.raise_for_status() # 请求异常时直接抛出错误,方便排查 # 解码内容并解析为Python字典 raw_content = base64.b64decode(response.text) log_list_data = json.loads(raw_content) # 按要求整理结构 formatted_result = [] for operator in log_list_data["operators"]: current_op = { "name": operator["name"], "logs": [] } for log_item in operator["logs"]: current_op["logs"].append({ "description": log_item["description"], "log_id": log_item["log_id"] }) formatted_result.append(current_op) # 打印格式化后的结果 print(json.dumps(formatted_result, indent=2, ensure_ascii=False)) # 如需保存到本地文件,取消以下注释即可 # with open("ct_logs_result.json", "w", encoding="utf-8") as f: # json.dump(formatted_result, f, indent=2, ensure_ascii=False)
补充说明
- 代码运行后直接输出你要求的结构,无任何冗余字段
- 如果需要过滤非可用状态的日志,可在遍历
logs时增加状态判断,比如仅保留state字段标记为usable的日志 - 该方案直接对接原始数据源,不会因为代码托管平台的页面样式、DOM结构调整导致提取逻辑失效,可长期稳定运行
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

