快速上手¶
概述¶
本文档带你从安装到第一个完整查询,覆盖 igapi 最常用的功能路径。igapi 是对 Instagram 私有 API 的 Python 封装,底层由 Rust 实现,通过 PyO3 桥接到 Python,提供异步调用接口。
igapi 提供两种客户端:
Client(Android 平台):模拟 Instagram Android 客户端,适用于绝大多数场景,支持用户搜索、Feed 浏览、图片上传WebClient(Web 平台):模拟 Instagram Web 端,支持完整的 2FA 自动处理、GraphQL 帖子查询和一步式图片发布
本文档以 Android 客户端为主线展示核心流程,最后一节介绍 Web 客户端入口。两种客户端的完整对比详见平台选择。
安装¶
从 PyPI 安装预编译二进制包,无需本地 Rust 环境:
验证安装是否成功:
包名与导入名的区别
PyPI 包名是 igapi-rs(含连字符),但 Python 中的导入名是 igapi(不含连字符)。
完整的安装说明和常见问题请参阅安装文档。
第一步:创建客户端并登录¶
创建 Android 客户端¶
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 接受 Client 或 WebClient 实例,两种客户端均可使用。
按用户 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():
# 按关键词搜索,返回匹配的用户列表
users = await user_api.search("python")
for user in users:
print(f"@{user.username} - {user.full_name}")
搜索结果类型为 list[User],其中 follower_count 和 following_count 固定为 0(搜索结果不包含该信息)。如需完整粉丝数据,调用 user_api.info(user.pk) 单独查询。
浏览用户 Feed¶
FeedApi 提供用户帖子的分页获取和全量获取两种方式。
创建 FeedApi 实例¶
分页获取(手动翻页)¶
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 独有)¶
PostApi 仅 WebClient 可用,支持通过用户名直接查询公开帖子:
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 管理的完整流程。
- 平台选择:系统对比
Client和WebClient的功能差异,帮助你为具体场景做出正确选择 - 安装文档:常见安装问题排查和从源码构建说明
- 进阶功能:图片上传请参阅
UploadApi的使用说明;媒体信息查询请参阅MediaApi
如遇到问题,欢迎在 GitHub Issues 提交反馈。