跳转至

快速上手

概述

本文档带你从安装到第一个完整查询,覆盖 igapi 最常用的功能路径。igapi 是对 Instagram 私有 API 的 Python 封装,底层由 Rust 实现,通过 PyO3 桥接到 Python,提供异步调用接口。

igapi 提供两种客户端:

  • Client(Android 平台):模拟 Instagram Android 客户端,适用于绝大多数场景,支持用户搜索、Feed 浏览、图片上传
  • WebClient(Web 平台):模拟 Instagram Web 端,支持完整的 2FA 自动处理、GraphQL 帖子查询和一步式图片发布

本文档以 Android 客户端为主线展示核心流程,最后一节介绍 Web 客户端入口。两种客户端的完整对比详见平台选择


安装

从 PyPI 安装预编译二进制包,无需本地 Rust 环境:

pip install igapi-rs

验证安装是否成功:

python -c "import igapi; print('igapi-rs 安装成功')"

包名与导入名的区别

PyPI 包名是 igapi-rs(含连字符),但 Python 中的导入名是 igapi(不含连字符)。

完整的安装说明和常见问题请参阅安装文档


第一步:创建客户端并登录

创建 Android 客户端

import igapi

# 创建默认 Android 客户端
client = igapi.Client()

Client 构造函数支持以下可选参数:

参数 类型 默认值 说明
proxy str \| None None HTTP 代理地址,例如 "http://127.0.0.1:8080"
danger_accept_invalid_certs bool False 跳过 TLS 证书验证,配合抓包代理使用
http1_only bool False 强制使用 HTTP/1.1,配合抓包代理使用
account AccountInfo \| None None 从已有账号信息恢复 session,跳过登录步骤

配合代理抓包时,三个参数通常一起使用:

client = igapi.Client(
    proxy="http://127.0.0.1:8080",
    danger_accept_invalid_certs=True,
    http1_only=True,
)

登录

import asyncio
import igapi

async def main():
    client = igapi.Client()

    try:
        await client.login("your_username", "your_password")
        print("登录成功")
        print(await client.is_logged_in())  # True
    except igapi.TwoFactorRequired:
        # 账号开启了双因素认证(2FA)
        # Android 客户端需手动处理,推荐改用 WebClient 并传入 two_fa_secret 自动完成
        print("需要双因素认证,请参考下方 Web 客户端章节")
    except igapi.ChallengeRequired:
        # Instagram 要求完成安全挑战(如短信验证码确认)
        print("需要完成安全验证,请登录 Instagram App 手动确认")
    except ValueError as e:
        # 密码错误(BadPassword)或用户名无效(InvalidUser)
        print(f"登录失败:{e}")
    except PermissionError as e:
        # 账号被锁定(AccountLocked)或需要同意条款(ConsentRequired)
        print(f"账号受限:{e}")

asyncio.run(main())

is_logged_in() 返回 True 表示当前 session 有效,可以继续调用后续 API。


查询用户信息

登录后,通过 UserApi 查询用户信息和搜索用户。

获取 UserApi 实例

import asyncio
import igapi

async def main():
    client = igapi.Client()
    await client.login("your_username", "your_password")

    user_api = igapi.UserApi(client)

asyncio.run(main())

UserApi 接受 ClientWebClient 实例,两种客户端均可使用。

按用户 ID 查询详细信息

async def main():
    # 按用户 ID 查询完整的用户信息
    user = await user_api.info(25025320)

    print(user.pk)              # 用户 ID(int)
    print(user.username)        # 用户名(str,不含 @)
    print(user.full_name)       # 显示名称(str)
    print(user.follower_count)  # 粉丝数(int)
    print(user.following_count) # 关注数(int)
    print(user.is_private)      # 是否私密账号(bool)
    print(user.profile_pic_url) # 头像 URL(str)
    print(repr(user))
    # 输出:User(pk=25025320, username='instagram', full_name='Instagram', followers=..., following=...)

用户名转用户 ID

很多 API 需要用户 ID(pk)而非用户名。id_from_username() 提供直接转换:

async def main():
    user_id = await user_api.id_from_username("instagram")
    print(user_id)  # 25025320

搜索用户

async def main():
    # 按关键词搜索,返回匹配的用户列表
    users = await user_api.search("python")

    for user in users:
        print(f"@{user.username} - {user.full_name}")

搜索结果类型为 list[User],其中 follower_countfollowing_count 固定为 0(搜索结果不包含该信息)。如需完整粉丝数据,调用 user_api.info(user.pk) 单独查询。


浏览用户 Feed

FeedApi 提供用户帖子的分页获取和全量获取两种方式。

创建 FeedApi 实例

feed_api = igapi.FeedApi(client)
user_id = 25025320

分页获取(手动翻页)

async def main():
    # 第一页,不传 max_id 则从最新帖子开始
    items, cursor = await feed_api.user(user_id)

    for item in items:
        print(item.id)            # 媒体 ID(str)
        print(item.media_type)    # 媒体类型:1=图片,2=视频,8=轮播图集
        print(item.caption_text)  # 文案(str,无文案时为空字符串)
        print(item.like_count)    # 点赞数(int)
        print(item.comment_count) # 评论数(int)

    print(f"本页 {len(items)} 条,下一页游标:{cursor}")

    # 翻到下一页(cursor 为 None 表示已到最后一页)
    if cursor:
        items2, cursor2 = await feed_api.user(user_id, max_id=cursor)
        print(f"第二页 {len(items2)} 条")

全量获取(自动分页)

async def main():
    # 获取最多 50 条帖子(内部自动循环翻页)
    all_items = await feed_api.user_all(user_id, limit=50)
    print(f"共获取 {len(all_items)} 条帖子")

    # 不传 limit 时默认最多 100 条
    all_items = await feed_api.user_all(user_id)

user_all() 内部自动处理分页,直到达到 limit 数量或到达最后一页为止。目标用户帖子较多时,建议设置合理的 limit 以控制请求频率。


保存和恢复 Session

每次调用 login() 都会向 Instagram 服务器发起完整的登录请求,频繁登录可能触发风控。推荐将登录后的 session 导出保存,下次启动时直接恢复,无需重新登录。

导出 Session

import asyncio
import igapi

async def main():
    client = igapi.Client()
    await client.login("your_username", "your_password")

    # 方式一:导出为字符串(便于存储到文件或数据库)
    account_str = client.export_account_string()
    # 字符串格式:用户名:密码||android_id;phone_id;uuid;device_id|cookies||

    # 方式二:导出为 AccountInfo 对象,可访问各字段
    account = client.export_account()
    print(account.username)    # 用户名(str)
    print(account.platform)    # PlatformType.Android
    print(account.has_session) # True,表示含有有效 session
    print(account.user_id)     # 用户 ID(int)
    print(account.android_id)  # Android 设备 ID(str)
    print(account.session_id)  # Session ID 原始值(str)

    # 将字符串保存到文件
    with open("session.txt", "w") as f:
        f.write(account_str)
    print("Session 已保存")

asyncio.run(main())

安全提示

session.txt 包含账号凭据(密码 + cookies),请将其加入 .gitignore,不要提交到版本控制系统。

恢复 Session

import asyncio
import igapi
from igapi import PlatformType

async def main():
    # 从文件读取 session 字符串
    with open("session.txt", "r") as f:
        account_str = f.read().strip()

    # 解析为 AccountInfo(必须指定正确的 platform)
    account = igapi.AccountInfo.parse(account_str, PlatformType.Android)

    print(account.has_session)  # True
    print(account.user_id)      # 用户 ID

    # 从 AccountInfo 创建客户端,直接可用,无需再次调用 login()
    client = igapi.Client(account=account)
    print(await client.is_logged_in())  # True

    # 继续使用各 API
    user_api = igapi.UserApi(client)
    user = await user_api.info(account.user_id)
    print(f"已恢复账号:{user.username}")

asyncio.run(main())

完整的 Session 管理示例

以下是一个生产可用的 session 管理模式,优先从文件恢复,失效时重新登录:

import asyncio
import igapi
import os
from igapi import PlatformType

SESSION_FILE = "session.txt"

async def get_client(username: str, password: str) -> igapi.Client:
    """获取客户端:优先从 session 文件恢复,session 失效则重新登录"""
    if os.path.exists(SESSION_FILE):
        with open(SESSION_FILE, "r") as f:
            account_str = f.read().strip()
        if account_str:
            try:
                account = igapi.AccountInfo.parse(account_str, PlatformType.Android)
                client = igapi.Client(account=account)
                if await client.is_logged_in():
                    print("已从 session 恢复登录状态")
                    return client
            except Exception:
                pass  # session 损坏,重新登录

    # session 不存在或已失效,执行完整登录
    client = igapi.Client()
    await client.login(username, password)
    print("登录成功,保存 session")

    with open(SESSION_FILE, "w") as f:
        f.write(client.export_account_string())

    return client


async def main():
    client = await get_client("your_username", "your_password")

    user_api = igapi.UserApi(client)
    user = await user_api.info(25025320)
    print(f"用户名:{user.username},粉丝数:{user.follower_count}")

if __name__ == "__main__":
    asyncio.run(main())

使用 Web 客户端

WebClient 模拟 Instagram Web 端,相比 Client 的核心优势:

  • 内置完整的 2FA 自动处理(传入 TOTP Secret 即可)
  • 专有 PostApi:通过 GraphQL 查询帖子、一步式图片发布
  • session 格式与 Android 客户端不同,互不通用

创建并登录

import asyncio
import igapi

async def main():
    web = igapi.WebClient()

    # 无 2FA 账号:直接登录
    await web.login("your_username", "your_password")
    print(await web.is_logged_in())  # True

asyncio.run(main())

自动处理 2FA(推荐)

账号开启了双因素认证时,传入 TOTP Secret,SDK 自动生成验证码完成登录:

import asyncio
import igapi

async def main():
    web = igapi.WebClient()

    # two_fa_secret 是 Authenticator App 中显示的密钥,Base32 编码格式
    await web.login(
        "your_username",
        "your_password",
        two_fa_secret="JBSWY3DPEHPK3PXP"
    )
    print(await web.is_logged_in())  # True

asyncio.run(main())

手动处理 2FA

如果不方便提前配置 TOTP Secret,也可以捕获异常后手动输入验证码:

import asyncio
import igapi

async def main():
    web = igapi.WebClient()

    try:
        await web.login("your_username", "your_password")
    except igapi.TwoFactorRequired:
        # 调用 verify_two_factor() 完成验证,无需再传 username/password
        code = input("请输入双因素验证码(6 位数字):")
        await web.verify_two_factor(code)

    print(await web.is_logged_in())  # True

asyncio.run(main())

使用 PostApi 查询帖子(Web 独有)

PostApiWebClient 可用,支持通过用户名直接查询公开帖子:

import asyncio
import igapi

async def main():
    web = igapi.WebClient()
    await web.login("your_username", "your_password")

    post_api = igapi.PostApi(web)

    # 按用户名查询帖子列表(无需先获取 user_id)
    posts, cursor = await post_api.user_posts("instagram", count=12)
    for post in posts:
        print(f"{post.id} | 点赞:{post.like_count} | 文案:{post.caption_text[:30]}")

    # 翻到下一页
    if cursor:
        posts2, cursor2 = await post_api.user_posts("instagram", count=12, after=cursor)

    # 一步式发布图片(上传 + 配置 合并为单次调用)
    with open("photo.jpg", "rb") as f:
        image_data = f.read()

    media = await post_api.create_photo(
        image_data,
        width=1080,
        height=1080,
        caption="这是通过 igapi 发布的帖子 #python"
    )
    print(f"发布成功,帖子 ID:{media.id}")

asyncio.run(main())

Web 客户端的 Session 管理

Web 客户端的 session 管理方式与 Android 相同,仅 platform 参数传入 PlatformType.Web

import asyncio
import igapi
from igapi import PlatformType

async def main():
    web = igapi.WebClient()
    await web.login("your_username", "your_password")

    # 导出
    account_str = web.export_account_string()
    with open("session_web.txt", "w") as f:
        f.write(account_str)

    # 恢复(必须指定正确的平台类型)
    with open("session_web.txt", "r") as f:
        account_str = f.read().strip()

    account = igapi.AccountInfo.parse(account_str, PlatformType.Web)
    web2 = igapi.WebClient(account=account)
    print(await web2.is_logged_in())  # True

asyncio.run(main())

Session 不可混用

Android session 和 Web session 格式不同,AccountInfo.parse() 时必须指定正确的 platform,否则解析会失败或产生无效 session。


下一步

恭喜,你已经完成了 igapi 的基础入门,掌握了登录、查询用户、浏览 Feed 和 Session 管理的完整流程。

  • 平台选择:系统对比 ClientWebClient 的功能差异,帮助你为具体场景做出正确选择
  • 安装文档:常见安装问题排查和从源码构建说明
  • 进阶功能:图片上传请参阅 UploadApi 的使用说明;媒体信息查询请参阅 MediaApi

如遇到问题,欢迎在 GitHub Issues 提交反馈。