You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用HaveIBeenPwned API遇TypeError及数据遍历问题求助

解决HaveIBeenPwned API调用的几个问题

我来帮你一步步搞定遇到的这些问题:

1. 先解决 TypeError: string indices must be integers 错误

这个错误的核心是你把字符串当成字典来访问了,通常发生在API返回非预期响应的时候——比如当邮箱没有泄露记录时,HIBP API会返回404状态码,响应内容不是你预期的JSON数组,这时候强行解析后得到的是字符串,再用['Title']这种字典索引去访问就会触发错误。

你需要先检查API的响应状态,处理非200的情况:

def DataGetCurrent(Username):
    SearchURL = "https://haveibeenpwned.com/api/v2/breachedaccount/{}".format(Username)
    try:
        request = url.urlopen(url.Request(SearchURL, headers={'User-Agent' : "Mozilla/5.0"}))
        # 先确认响应正常
        if request.getcode() != 200:
            return None
        data = request.read().decode("utf-8")
        json_data = json.loads(data)
        return json_data  # 返回整个结果数组,不是第一个元素
    except Exception as e:
        print(f"请求出错了: {str(e)}")
        return None

2. 遍历所有泄露条目并统计数量

之前你只返回了json_data[0],自然只能拿到第一个条目。现在我们返回整个数组,然后遍历它就能统计数量并输出所有内容:
修改EmailSearch函数:

def EmailSearch():
    email = input("Please enter the Email that's going to be searched \n: ")
    data_list = DataGetCurrent(email)
    
    if not data_list:
        print("你的邮箱没有被泄露的记录哦。")
        return
    
    # 统计泄露次数
    breach_count = len(data_list)
    print(f"你的邮箱一共涉及 {breach_count} 次数据泄露:\n")
    
    # 遍历所有泄露条目
    for idx, breach in enumerate(data_list, 1):
        # 处理DataClasses列表,转成易读的字符串
        leaked_data = ", ".join(breach['DataClasses'])
        print(f"=== 第 {idx} 次泄露 ===")
        print(f"标题: {breach['Title']}")
        print(f"网站: {breach['Domain']}")
        print(f"泄露日期: {breach['BreachDate']}")
        print(f"泄露详情: {breach['Description']}")
        print(f"泄露的数据类型: {leaked_data}\n")

3. 正确提取和打印DataClasses

DataClasses是一个数组(比如['Email addresses', 'Passwords']),直接打印会显示列表格式,用", ".join(breach['DataClasses'])就能把它转换成逗号分隔的友好格式。

完整修改后的代码

把这些修改整合后,最终代码如下:

# This program aims to provide 4 search functions by which users can test if their data is at risk.
import urllib.request as url
import json

def UsernameSearch():
    print("已选择用户名搜索功能!")

def PasswordSearch():
    print("已选择密码搜索功能!")

def EmailSearch():
    email = input("请输入要查询的邮箱地址 \n: ")
    
    def DataGetCurrent(username):
        SearchURL = "https://haveibeenpwned.com/api/v2/breachedaccount/{}".format(username)
        try:
            request = url.urlopen(url.Request(SearchURL, headers={'User-Agent' : "Mozilla/5.0"}))
            if request.getcode() != 200:
                return None
            data = request.read().decode("utf-8")
            return json.loads(data)
        except Exception as e:
            print(f"请求出错: {str(e)}")
            return None
    
    data_list = DataGetCurrent(email)
    
    if not data_list:
        print("你的邮箱没有被泄露的记录。")
        return
    
    breach_count = len(data_list)
    print(f"你的邮箱一共涉及 {breach_count} 次数据泄露:\n")
    
    for idx, breach in enumerate(data_list, 1):
        leaked_data = ", ".join(breach['DataClasses'])
        print(f"=== 第 {idx} 次泄露 ===")
        print(f"标题: {breach['Title']}")
        print(f"网站: {breach['Domain']}")
        print(f"泄露日期: {breach['BreachDate']}")
        print(f"泄露详情: {breach['Description']}")
        print(f"泄露的数据类型: {leaked_data}\n")

def SiteSearch():
    print("已选择网站搜索功能!")

def loop():
    try:
        answer = input("当前有5个选项: \n(1)用户名搜索 \n(2)密码搜索 \n(3)邮箱搜索 \n(4)网站搜索 \n(5)退出 \n \n:")
        answer_clean = answer.strip().upper()
        if answer_clean == "1":
            UsernameSearch()
        elif answer_clean == "2":
            PasswordSearch()
        elif answer_clean == "3":
            EmailSearch()
        elif answer_clean == "4":
            SiteSearch()
        elif answer_clean == "5" or answer_clean == "EXIT":
            print("正在退出程序...")
            return
        else:
            print("\n输入无效,请重新尝试!\n")
            loop()
    except KeyboardInterrupt:
        print("\n不用这么急着退出啦,输入\"exit\"或者\"5\"就能正常退出程序!\n")
        loop()

loop()

额外优化的小细节

  • 把变量名Username改成了email,更符合语义;
  • 给退出选项增加了对"EXIT"和"5"的支持,用户操作更方便;
  • 增加了异常捕获,处理网络波动等可能的请求错误;
  • 用enumerate给每个泄露条目加上序号,输出更清晰。

内容的提问来源于stack exchange,提问作者JohnSmith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:14:14