使用Pandas将域名查询API响应转换为单行CSV记录的方法
域名资源信息转单行CSV实现方案
问题背景
遍历域名列表采集相关信息时,需要将API返回的响应结果转换为单行CSV格式记录,但始终无法调整出正确的数据格式。核心难点包括:
- 不同API响应中同域名下的资源数量不固定(例如存在多个NS类型资源的场景)
- 要求同一域名下的所有资源横向排列在同一行:首列为domain域名,后续每两列依次对应一组资源的Resource Type、ipv4字段
- 此前尝试用Pandas实现未成功,目前仅完成遍历输入CSV中域名字段的循环逻辑,需要可落地的实现方案
给定API响应示例
注:原提供的响应内容存在JSON语法错误,以下为修正后可正常解析的版本
[ { "domainName":"something I made up.com", "resourceType":"web", "ipv4":"34.102.136.180", "geolocation":{ "city":"The Greenhouse", "country":"US", "latitude":"37.41889", "longitude":"-122.10361", "postalCode":"", "region":"California", "timezone":"-07:00" } }, { "domainName":"somethingimadeup.com", "resourceType":"ns", "ipv4":"34.102.136.180", "geolocation":{ "city":"The Greenhouse", "country":"US", "latitude":"37.41889", "longitude":"-122.10361", "postalCode":"", "region":"California", "timezone":"-07:00" } }, { "domainName":"ns03.domaincontrol.com", "resourceType":"www.web", "ipv4":"97.74.101.2", "geolocation":{ "city":"Sweetwater Ranch", "country":"US", "latitude":"33.60421", "longitude":"-111.8882", "postalCode":"", "region":"Arizona", "timezone":"-07:00" } } ]
实现思路
核心逻辑是先按域名分组聚合所有关联资源,再根据所有域名下的最大资源数动态生成CSV表头,逐行写入时自动补空值对齐列数,不需要硬编码固定列数,完美适配资源数量不固定的场景。全程用Python标准库实现,不需要额外依赖,对新手友好。
完整实现代码
import csv import json from collections import defaultdict # -------------------------- # 对接你现有逻辑的部分 # -------------------------- # 初始化域名-资源映射字典,key为域名,value为该域名下(资源类型, ipv4)元组的列表 domain_res_map = defaultdict(list) # 这里替换成你已有的遍历输入CSV、调用API的逻辑 # 每次拿到单条API返回的资源条目后,执行以下逻辑加入映射即可: # for item in 单域名API返回的资源列表: # domain = item["domainName"] # res_type = item["resourceType"] # ipv4 = item["ipv4"] # domain_res_map[domain].append( (res_type, ipv4) ) # 以下为测试用模拟数据加载逻辑,正式使用时替换为你的API响应处理逻辑即可 demo_resp = [ { "domainName":"something I made up.com", "resourceType":"web", "ipv4":"34.102.136.180", "geolocation":{ "city":"The Greenhouse", "country":"US", "latitude":"37.41889", "longitude":"-122.10361", "postalCode":"", "region":"California", "timezone":"-07:00" } }, { "domainName":"somethingimadeup.com", "resourceType":"ns", "ipv4":"34.102.136.180", "geolocation":{ "city":"The Greenhouse", "country":"US", "latitude":"37.41889", "longitude":"-122.10361", "postalCode":"", "region":"California", "timezone":"-07:00" } }, { "domainName":"ns03.domaincontrol.com", "resourceType":"www.web", "ipv4":"97.74.101.2", "geolocation":{ "city":"Sweetwater Ranch", "country":"US", "latitude":"33.60421", "longitude":"-111.8882", "postalCode":"", "region":"Arizona", "timezone":"-07:00" } } ] for item in demo_resp: domain = item["domainName"] res_type = item["resourceType"] ipv4 = item["ipv4"] domain_res_map[domain].append( (res_type, ipv4) ) # -------------------------- # CSV生成部分 # -------------------------- # 1. 计算所有域名下的最大资源数,确定CSV总列数 max_res_count = max(len(res_list) for res_list in domain_res_map.values()) # 2. 动态生成表头:首列为domain,后续每两列对应第N组的资源类型、IP header = ["domain"] for idx in range(1, max_res_count + 1): header.append(f"resource_type_{idx}") header.append(f"ipv4_{idx}") # 3. 逐行写入CSV with open("domain_resource_output.csv", "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerow(header) for domain, res_list in domain_res_map.items(): row = [domain] # 把当前域名下的所有资源按两列一组写入行 for res_type, ipv4 in res_list: row.extend([res_type, ipv4]) # 资源数不足最大值时补空字符串,保证列对齐 row.extend([""] * (len(header) - len(row))) writer.writerow(row)
效果说明
- 生成的CSV首列为域名,后续列按资源顺序依次排列资源类型、对应IP
- 单个域名下资源数不影响格式,资源多的域名自动占更多列,资源少的域名对应列留空,不会出现错位
- 如果后续需要新增地理位置等字段,只需要在分组阶段提取对应字段,同步修改表头生成和行写入逻辑即可,扩展成本低
内容的提问来源于stack exchange,提问作者Shawn
相关产品推荐
相关产品推荐

