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

如何在Python循环中处理Instagram意外JSON响应

解决方案

看起来你遇到的核心问题是两点:一是无效账号导致的JSON解析/结构访问崩溃,二是处理失败后重复抓取同一账号。我来给你一套完整的解决方案,亲测有效:

1. 用异常捕获处理无效账号的解析错误

当请求不存在的Instagram用户页面时,返回的内容要么不是有效JSON,要么没有entry_data['ProfilePage']结构。我们需要在extract_json_data函数里加入全面的异常捕获,覆盖JSON解析失败、键不存在、索引不存在的情况,遇到无效账号时返回None而非崩溃。

修改后的extract_json_data示例:

import json

def extract_json_data(page_content):
    try:
        # 先定位Instagram页面中嵌入的JSON数据(这步很关键,原代码可能漏了)
        start_marker = 'window._sharedData = '
        end_marker = ';</script>'
        start_idx = page_content.find(start_marker) + len(start_marker)
        end_idx = page_content.find(end_marker, start_idx)
        
        stringified_json = page_content[start_idx:end_idx]
        data = json.loads(stringified_json)
        # 提取目标结构
        return data['entry_data']['ProfilePage'][0]
    except (json.decoder.JSONDecodeError, KeyError, IndexError, ValueError) as e:
        print(f"解析账号失败: {str(e)}")
        return None

2. 修复重复处理问题:处理后立即更新数据库状态

重复抓取同一账号的根源是:你获取未检查账号后,即使处理失败也没有标记为已处理,下次查询数据库时会再次拿到它。解决办法是每次只取一个未检查账号,处理完成(无论成功/失败)都立即更新数据库状态。

这里给你一套完整的主循环+数据库操作逻辑:

import requests
import time

def get_unchecked_username(db_cursor):
    # 每次只取一个未检查的账号,避免批量处理时的重复问题
    db_cursor.execute("SELECT username FROM ig_users_raw WHERE checked = FALSE LIMIT 1")
    result = db_cursor.fetchone()
    return result[0] if result else None

def update_account_status(db_cursor, db_conn, username, is_valid=True):
    if is_valid:
        # 有效账号标记为已检查
        db_cursor.execute("UPDATE ig_users_raw SET checked = TRUE WHERE username = %s", (username,))
    else:
        # 无效账号直接从数据库删除(也可以标记为invalid,看你需求)
        db_cursor.execute("DELETE FROM ig_users_raw WHERE username = %s", (username,))
    db_conn.commit()

def request_instagram_page(username):
    url = f"https://www.instagram.com/{username}/"
    # 必须加User-Agent,否则Instagram会返回403
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
    }
    try:
        response = requests.get(url, headers=headers, timeout=12)
        response.raise_for_status()  # 捕获404、500等HTTP错误
        return response.text
    except requests.exceptions.RequestException as e:
        print(f"请求账号{username}失败: {str(e)}")
        return None

# 主循环(假设你已经有数据库连接和cursor)
while True:
    username = get_unchecked_username(db_cursor)
    if not username:
        # 没有未处理账号时,休息10分钟再轮询
        print("暂无未处理账号,10分钟后重试...")
        time.sleep(600)
        continue

    print(f"正在处理账号: {username}")
    page_content = request_instagram_page(username)

    if not page_content:
        # 请求失败,标记为无效账号
        update_account_status(db_cursor, db_conn, username, is_valid=False)
        time.sleep(2)  # 加延迟避免被封禁
        continue

    profile_data = extract_json_data(page_content)
    if profile_data:
        # 成功获取数据,这里可以添加保存数据的逻辑
        print(f"成功抓取{username}的资料")
        # save_to_database(profile_data)
        update_account_status(db_cursor, db_conn, username, is_valid=True)
    else:
        # 无效账号,更新状态
        print(f"账号{username}不存在或无效")
        update_account_status(db_cursor, db_conn, username, is_valid=False)

    time.sleep(2)

3. 关键注意点

  • 数据库查询逻辑:必须用LIMIT 1每次只取一个账号,处理完立即提交更新,彻底杜绝重复处理。
  • 请求头设置:一定要带上User-Agent,否则Instagram会直接返回403禁止访问,导致解析失败。
  • 防封禁策略:添加2秒左右的请求延迟,避免短时间内大量请求被Instagram限制IP。
  • 异常覆盖:除了JSON相关异常,还要捕获HTTP请求的所有异常(超时、404等),这些情况都属于无效账号范畴。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:41:48