Python3从谷歌导出的嵌套结构历史JSON中提取URL的实现方法
谷歌历史导出文件爬取报错排查与修复
核心问题根源
你遇到的报错和源数据里的转义双引号没有关系,本质是代码逻辑完全不匹配官方导出的JSON结构,叠加多处语法、变量使用错误导致的,具体问题点:
- 数据层级遍历错误:官方导出的JSON中,所有历史访问条目都存放在根节点
Browser History对应的数组里,当前代码直接遍历根字典的键名,只会拿到字符串值"Browser History",根本取不到存了URL的条目对象,自然会报字段读取错误 - 参数传递错误:调用
getHtml函数时,把整个JSON文本内容当URL传入,没有传递当前遍历条目的url字段值 - 未定义变量误用:构造
BeautifulSoup对象时引用了没有赋值的markup变量,写输出文件时引用了没有初始化的计数器i - 配置逻辑失效:生成随机User-Agent的代码只写了字典字面量,没有实际绑定到请求头参数里,配置完全不生效
修复后的可运行代码
import requests from bs4 import BeautifulSoup from fake_useragent import UserAgent import json def getHtml(url): ua = UserAgent() headers = {'user-agent': ua.random} try: response = requests.get(url, timeout=10, headers=headers) response.raise_for_status() except Exception as e: print(f"请求{url}失败:{e}") return None return response.content if __name__ == "__main__": # 直接用json.load读取文件对象,避免手动读文本带来的编码问题 with open('urls.json', 'r', encoding='utf-8') as history: data = json.load(history) # 定位到实际存放历史条目的数组 history_items = data.get("Browser History", []) # 初始化输出文件的自增计数器 item_index = 0 for block in history_items: current_url = block["url"] print(f"scraping {current_url}...") html_content = getHtml(current_url) # 跳过请求失败的条目,避免空值报错 if not html_content: item_index += 1 continue soup = BeautifulSoup(html_content, "html5lib") page_text = soup.find_all(text=True) output = '' # 优化标签黑名单,过滤无效的脚本、样式内容 blacklist = [ "style", "script", "noscript", "iframe", "header", "footer" ] for text_node in page_text: if text_node.parent.name not in blacklist: output += f"{text_node} " # 指定utf-8编码写文件,避免中文乱码 with open(f"{item_index}.txt", "w", encoding="utf-8") as out_fd: out_fd.write(output) item_index += 1
关于源数据转义内容的说明
源数据里的\u003d、\u2013这类Unicode转义字符是JSON格式的标准组成部分,Python内置的json模块在解析时会自动完成转义字符的还原,不需要手动做正则替换、反转义这类额外操作,只要按正确的层级读取字段,就可以准确拿到URL内容。
内容的提问来源于stack exchange,提问作者Reijarmo
相关产品推荐
相关产品推荐

