平台选择¶
概述¶
igapi 支持两种客户端平台:Android(Client,模拟 Instagram 移动端 App)和 Web(WebClient,模拟浏览器)。两者共享大部分 API,但在登录方式、2FA 处理、专有功能和 session 格式上存在差异。
选对平台可以避免不必要的麻烦。本文档从功能对比到具体使用,帮助你快速做出决策。
功能对比表¶
| 特性 | Client(Android) |
WebClient(Web) |
|---|---|---|
用户信息查询 UserApi.info() |
支持 | 支持 |
用户搜索 UserApi.search() |
支持 | 不支持 |
用户名转 ID UserApi.id_from_username() |
支持 | 支持 |
媒体信息查询 MediaApi |
支持 | 支持 |
用户 Feed 获取 FeedApi |
支持 | 支持 |
图片上传(移动端接口)UploadApi.photo() |
支持 | 支持(photo_web()) |
图片发布配置 UploadApi.configure() |
支持 | 支持(configure_web()) |
GraphQL 帖子查询 PostApi.user_posts() |
不支持 | 支持 |
一步式图片发布 PostApi.create_photo() |
不支持 | 支持 |
| 2FA 自动处理(TOTP) | 不支持 | 支持 |
| 2FA 手动验证 | 需自行实现 | verify_two_factor() |
| session 持久化 | 支持 | 支持 |
| 代理配置 | 支持 | 支持 |
API 访问器汇总:
| API 类 | Client 可用 |
WebClient 可用 |
说明 |
|---|---|---|---|
UserApi |
是 | 是 | 用户信息查询和搜索 |
MediaApi |
是 | 是 | 单条媒体信息查询 |
FeedApi |
是 | 是 | 用户帖子分页/全量获取 |
UploadApi |
是 | 是(部分方法) | 图片上传(接口不同) |
PostApi |
否 | 是 | GraphQL 帖子查询 + 一步式发布(Web 独有) |
推荐场景¶
选择 Client(Android)的场景¶
- 账号没有开启 2FA,或 2FA 处理由外部系统管理
- 需要搜索用户功能(
UserApi.search(),Web 不支持) - 使用移动端图片上传接口(兼容性更好)
- 主要做数据采集,不需要 GraphQL 查询
import asyncio
import igapi
async def main():
client = igapi.Client()
await client.login("your_username", "your_password")
user_api = igapi.UserApi(client)
# 搜索用户(Web 端不支持此功能)
results = await user_api.search("travel photography")
for user in results:
print(f"@{user.username}: {user.follower_count} 粉丝")
# 获取用户 Feed
feed_api = igapi.FeedApi(client)
items, cursor = await feed_api.user(results[0].pk)
for item in items:
print(f"{item.id} | 点赞:{item.like_count}")
asyncio.run(main())
选择 WebClient(Web)的场景¶
- 账号开启了 2FA,希望 SDK 自动完成验证
- 需要通过用户名直接查询公开帖子(无需先转换 user_id)
- 需要一步式图片发布(上传 + 配置合并为单次调用)
- 需要 GraphQL 查询获取更丰富的帖子数据
import asyncio
import igapi
async def main():
web = igapi.WebClient()
# 传入 TOTP Secret,SDK 自动完成 2FA 验证
await web.login("your_username", "your_password", two_fa_secret="YOUR_TOTP_SECRET")
post_api = igapi.PostApi(web)
# 通过用户名直接查询(无需先获取 user_id)
posts, cursor = await post_api.user_posts("natgeo", count=12)
for post in posts:
print(f"{post.id} | 点赞:{post.like_count}")
asyncio.run(main())
Android 客户端详情¶
登录¶
import asyncio
import igapi
async def main():
client = igapi.Client()
try:
await client.login("your_username", "your_password")
except igapi.TwoFactorRequired as e:
# 抛出此异常时,e.two_factor_info 包含 2FA 元数据(dict 格式)
# 当前版本的 Android 客户端 2FA 需手动构造后续请求
# 建议改用 WebClient 处理 2FA 账号
print("该账号开启了 2FA,推荐改用 WebClient")
raise
except igapi.ChallengeRequired as e:
# e.challenge_info 包含挑战验证信息(dict 格式)
# 需要在 Instagram App 中手动确认后再重试
print("需要完成安全挑战,请在 Instagram App 中确认")
raise
except ValueError:
print("密码错误或用户名无效")
raise
asyncio.run(main())
图片上传(两步流程)¶
Android 平台图片上传分为两步:先上传原始文件,再配置发布:
import asyncio
import igapi
async def main():
client = igapi.Client()
await client.login("your_username", "your_password")
upload_api = igapi.UploadApi(client)
# 第一步:上传图片,获取 upload_id
with open("photo.jpg", "rb") as f:
image_data = f.read()
result = await upload_api.photo(image_data)
print(f"上传成功,upload_id:{result.upload_id}")
# 第二步:配置并发布
media = await upload_api.configure(
result.upload_id,
caption="通过 igapi 发布的帖子 #python",
disable_comments=False,
hide_like_count=False,
)
print(f"发布成功,帖子 ID:{media.id}")
asyncio.run(main())
Session 格式¶
Android 客户端 session 字符串的格式为:
导出和恢复:
from igapi import PlatformType
# 导出
account_str = client.export_account_string()
account = client.export_account() # AccountInfo 对象
# AccountInfo 字段(Android 平台特有)
print(account.platform) # PlatformType.Android
print(account.android_id) # Android 设备 ID
print(account.phone_id) # Phone ID
print(account.uuid) # UUID
print(account.device_id) # Device ID
print(account.user_id) # 用户 ID(int)
print(account.session_id) # Session ID
# 恢复
account = igapi.AccountInfo.parse(account_str, PlatformType.Android)
client = igapi.Client(account=account)
Web 客户端详情¶
登录(三种模式)¶
模式一:无 2FA 直接登录
import asyncio
import igapi
async def main():
web = igapi.WebClient()
await web.login("your_username", "your_password")
asyncio.run(main())
模式二:传入 TOTP Secret,自动完成 2FA(推荐)
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")
asyncio.run(main())
模式三:捕获异常后手动输入验证码
import asyncio
import igapi
async def main():
web = igapi.WebClient()
try:
await web.login("your_username", "your_password")
except igapi.TwoFactorRequired:
# verify_two_factor() 内部自动复用 login() 时的 username/password
code = input("请输入 6 位验证码:")
await web.verify_two_factor(code)
print(await web.is_logged_in()) # True
asyncio.run(main())
图片发布(一步流程)¶
Web 平台通过 PostApi.create_photo() 将上传和发布合并为单次调用:
import asyncio
import igapi
async def main():
web = igapi.WebClient()
await web.login("your_username", "your_password")
post_api = igapi.PostApi(web)
with open("photo.jpg", "rb") as f:
image_data = f.read()
# 一步完成:上传 + 配置发布
media = await post_api.create_photo(
image_data,
width=1080,
height=1080,
caption="Web 端一步式发布 #igapi",
disable_comments=False,
hide_like_count=False,
)
print(f"发布成功,帖子 ID:{media.id}")
asyncio.run(main())
也可以使用 UploadApi 的 Web 专用方法手动分步操作:
async def main():
upload_api = igapi.UploadApi(web)
# 第一步:Web 端上传(需要指定图片尺寸)
result = await upload_api.photo_web(image_data, width=1080, height=1080)
# 第二步:Web 端配置发布
media = await upload_api.configure_web(result.upload_id, caption="手动分步发布")
Session 格式¶
Web 客户端 session 字符串的格式为:
导出和恢复:
from igapi import PlatformType
# 导出
account_str = web.export_account_string()
account = web.export_account() # AccountInfo 对象
# AccountInfo 字段(Web 平台特有)
print(account.platform) # PlatformType.Web
print(account.csrf_token) # CSRF Token
print(account.mid) # Machine ID
print(account.user_id) # 用户 ID(int)
# 恢复(必须指定正确的平台类型)
account = igapi.AccountInfo.parse(account_str, PlatformType.Web)
web2 = igapi.WebClient(account=account)
如何切换平台¶
如果你已经在用 Android 客户端,想切换到 Web 客户端,需要重新登录获取 Web session。两种 session 格式不同,不能直接转换。
import asyncio
import igapi
async def main():
USERNAME = "your_username"
PASSWORD = "your_password"
# 原有的 Android 客户端
android_client = igapi.Client()
await android_client.login(USERNAME, PASSWORD)
# 创建 Web 客户端(独立登录,独立 session)
web_client = igapi.WebClient()
await web_client.login(USERNAME, PASSWORD)
# 两个客户端可以同时运行,互不影响
user_api = igapi.UserApi(android_client)
post_api = igapi.PostApi(web_client)
asyncio.run(main())
同一程序中两种客户端可以并存,分别承担各自擅长的任务:
import asyncio
import igapi
async def main():
# Android 客户端负责用户搜索
android_client = igapi.Client()
await android_client.login("your_username", "your_password")
# Web 客户端负责帖子查询和发布
web_client = igapi.WebClient()
await web_client.login("your_username", "your_password")
user_api = igapi.UserApi(android_client)
post_api = igapi.PostApi(web_client)
# 用 Android 搜索用户
results = await user_api.search("travel")
if results:
target = results[0]
# 用 Web 查询该用户的帖子
posts, _ = await post_api.user_posts(target.username, count=12)
print(f"@{target.username} 最新 {len(posts)} 条帖子")
for post in posts:
print(f" {post.id} | 点赞:{post.like_count}")
asyncio.run(main())
常见问题¶
Q:我的账号有 2FA,只能用 WebClient 吗?¶
不是必须的。Android 客户端登录时如果触发 TwoFactorRequired 异常,可以从 e.two_factor_info 取出 2FA 元数据,自行构造验证请求。但这需要额外实现,工作量较大。
对于大多数场景,推荐直接使用 WebClient:传入 two_fa_secret 即可自动完成 TOTP 验证,无需任何额外代码。
Q:Android session 和 Web session 能否互相转换?¶
不能。两种 session 格式不同(Android 包含设备信息,Web 包含 CSRF Token),且 Instagram 服务器对两种客户端的认证方式不同,session 无法互换。切换平台需要重新登录。
Q:WebClient 的 UserApi.search() 为什么不能用?¶
Web 端的搜索接口与移动端不同,当前版本的 UserApi.search() 仅对接了移动端 API,因此只有 Client(Android 平台)支持。如果你同时需要搜索用户和 GraphQL 查询,可以创建两个客户端并存。
Q:PostApi.create_photo() 和 UploadApi 两步上传有什么区别?¶
PostApi.create_photo() 是 Web 端的一步式封装,内部将上传和发布配置合并为一次 Python 调用,使用更方便。UploadApi 的两步流程(photo_web() + configure_web())则提供更细粒度的控制,例如可以在上传后检查 upload_id 再决定是否发布。两者最终结果相同。
Q:两种客户端的 export_account_string() 格式有文档吗?¶
格式定义在各平台的 session 类型中:
- Android:
用户名:密码||android_id;phone_id;uuid;device_id|cookies|| - Web:
用户名:密码||csrf;;;|cookies||
其中 cookies 部分包含 sessionid、ds_user_id、csrftoken、mid 等字段,以分号分隔。通常不需要手动拼接这个字符串,使用 export_account_string() 导出、AccountInfo.parse() 恢复即可。