NiceDayZc/okgram

GitHub: NiceDayZc/okgram

一个手机级的 Instagram 私有 API Python 客户端,通过模拟真实 Android 设备的传输指纹与保持身份一致性来防止自动化会话被封禁。

Stars: 0 | Forks: 0

# okgram — Instagram Private API Python 客户端(手机级,防封号) ![Python](https://img.shields.io/badge/python-3.8%2B-blue) ![License: MIT](https://img.shields.io/badge/license-MIT-green) ![Transport](https://img.shields.io/badge/transport-OkHttp%20HTTP%2F2-orange) ![TLS](https://img.shields.io/badge/TLS-JA3%2FJA4%20impersonation-red) ![Endpoints](https://img.shields.io/badge/endpoints-348%2B%20methods-purple) 一个用于 **Instagram Private API** (`i.instagram.com/api/v1`) 的 Python 客户端, 通过对 **Instagram Lite 516.0.0.8.103** 及 Instagram Android 配置文件的逆向工程开发。 它被打包进一个 **单一类** `InstagramAPI` 中,涵盖了 **每一个端点类别**(19 个类别 / 348+ 个方法)。 它是 **手机级**的:它保持整个身份(设备 + `IG-U-RUR` 路由 + `X-MID` + `X-IG-WWW-Claim` + 地理位置 + app-id + OkHttp TLS)内部一致且 稳定,**自动将你的区域同步到任意国家的真实 IP**,重放 App 的冷启动,并提供了一个 `okgram` CLI,其中的 `doctor` 命令能准确告诉你 为什么 session 会被封。参见 **[手机级 session](#phone-grade-sessions--why-your-sessionid-stops-bouncing)**。 ## 安装 使用 **pip** 直接从 GitHub 安装 — 它会自动拉取所有依赖项: ``` pip install git+https://github.com/NiceDayZc/okgram.git ``` 固定分支 / 标签: ``` pip install "git+https://github.com/NiceDayZc/okgram.git@main" ``` 以后升级: ``` pip install --upgrade --force-reinstall "git+https://github.com/NiceDayZc/okgram.git" ``` 可编辑 / 开发安装(克隆仓库,然后进行修改): ``` git clone https://github.com/NiceDayZc/okgram.git cd okgram pip install -e . ``` 可选附加项: ``` # + Pillow (在上传时读取图片尺寸) pip install "okgram[media] @ git+https://github.com/NiceDayZc/okgram.git" # + 为 requests engine 提供 socks5 proxy 支持 pip install "okgram[socks] @ git+https://github.com/NiceDayZc/okgram.git" ``` **依赖项(会自动为你安装):** | 包 | 用途 | |---|---| | `requests` | 备用 HTTP 引擎 + cookie jar | | `pycryptodome` | 登录时的密码加密 (`#PWD_INSTAGRAM:4` = RSA + AES-GCM) | | `tls-client` | **推荐**引擎 — 模拟 Android 上的 OkHttp (HTTP/2 + OkHttp JA3/JA4) | | `curl_cffi` | 备选引擎 (curl-impersonate: 浏览器 TLS + HTTP/2) | 验证安装: ``` python -c "import okgram; print('okgram', okgram.__version__)" ``` 然后在你的代码中: ``` from okgram import OkGram # aliases: InstagramAPI, Client (same class) cl = OkGram() ``` ## HTTP 引擎 — 看起来像一部真实的手机 普通的 `requests` 很容易被检测到:它使用 Python 的 OpenSSL(这种 JA3/JA4 TLS 指纹 没有任何手机会产生)并使用 HTTP/1.1 通信,而 Instagram App 使用的是 **基于 OkHttp/BoringSSL 的 HTTP/2**。 此客户端抽象了 HTTP 层,并自动选择可用的最接近 App 的引擎: | `engine=` | TLS / HTTP | 指纹 | 备注 | |---|---|---|---| | `"auto"` (默认) | 选择已安装的最佳选项 | — | tls_client → curl_cffi → requests | | `"tls_client"` | **HTTP/2, OkHttp Android** | `t13d1513**h2**_…` (OkHttp) | **与 Instagram Android UA 最匹配** | | `"curl_cffi"` | HTTP/2, 浏览器 | `t13d1516h2_…` (Chrome) | 真正的非 Python TLS,浏览器配置 | | `"requests"` | HTTP/1.1, Python | `t13d1812**h1**_…` (被标记) | 仅用作备选 | ``` cl = InstagramAPI(device_seed="acct") # auto -> tls_client okhttp4_android_13 cl = InstagramAPI(engine="tls_client") # force OkHttp-Android impersonation cl = InstagramAPI(engine="tls_client", impersonate="okhttp4_android_12") cl = InstagramAPI(engine="curl_cffi", impersonate="chrome") ``` 使用 `tls_client` 时,OkHttp 配置会 **根据模拟设备的 Android 版本自动映射** (例如 Android 13 → `okhttp4_android_13`),因此 TLS 指纹、HTTP/2 设置、header 顺序和 `User-Agent` 都会保持一致 — 就像真实的 App 一样。(已端到端验证:请求以 `h2` 和 OkHttp JA3/JA4 发出,而不是 Python 的指纹。) ## 手机级 session — 为什么你的 `sessionid` 不再被封禁 Instagram **不是**仅凭 `sessionid` 来识别 session 的。它会将 `sessionid` + **设备** + `X-MID` + **`IG-U-RUR`**(区域路由) + `X-IG-WWW-Claim` + **出口 IP / 地理位置** + **app-id** 关联起来。如果其中任何一项 相互矛盾,IG 就会将其视为账号被接管 → `login_required` / 验证挑战 (可怕的“เด้ง”/封号)。okgram 现在保持整个身份 **内部一致 且稳定**,这才是让 session 保持活跃的真正原因: - **路由 header 捕获与回显。** `IG-U-RUR`、`IG-U-SHBID`、`IG-U-SHBTS`、 `IG-U-IG-DIRECT-REGION-HINT` 从每个响应中读取,并在每个 请求中回显(并持久化保存在 session 包中)。缺失 `IG-U-RUR` 是导致封号的主要原因 — 现在它已被端到端处理。 - **地理位置自动同步,适用于每个国家。** 客户端会检测你的 **真实出口 IP** 区域(如果有,则通过你的代理),并对齐 `country` / 区号 / `timezone` / `X-IG-EU-DC-ENABLED`,使得指纹永远不会与 网络矛盾。不再有“美国区域设置 + 曼谷时区”的不匹配。 - **实时的 app 配置。** `bloks_version_id` / 密码公钥 / 路由会 从 IG 自己的 `launcher/sync` + `qe/sync` 实时拉取,而不是使用过期数据。 - **冷启动行为。** 在启动时,它会重放 App 的真实序列 (timeline → stories → inbox → me),并带有可信的 `X-IG-Nav-Chain`,因此 session 不会“突然出现并立即采取行动”,像个 bot 一样。 - **稳定的 TLS。** OkHttp JA3/JA4 带有 **固定的**扩展顺序(为每个请求随机化 它本身就是一个 bot 信号)。 - **移动端与 Web 模式对比。** 从 **浏览器**导出的 `sessionid` 是一个绑定到 Web app-id 的 *Web* session。`mode="web"` 使用浏览器的 app-id / UA / Chrome TLS 与 `www.instagram.com` 通信 — 与该 session *保持源一致性*,因此 它比强行让 Web session 模拟手机被封禁的几率要小得多。 ### 一键启动(推荐) ``` from okgram import InstagramAPI cl = InstagramAPI(device_seed="") # auto_geo=True by default cl.bootstrap("") # geo→config→install→warmup cl.dump_settings("session.json") # save the full identity bundle print(cl.get_current_user()["username"]) ``` `bootstrap()` 按顺序运行:将区域对齐到你的 IP → 拉取实时配置 → 安装 session → 重放冷启动。以后可以使用完全相同的身份重新加载它: ``` cl = InstagramAPI() cl.load_settings("session.json") # restores device + rur + mid + claim + geo + mode ``` ### `okgram` CLI 安装此包的同时也会安装一个 `okgram` 命令(也可以通过 `python -m okgram` 调用): ``` # 将 browser sessionid 安装为 phone-grade session 并保存 okgram import "25025320%3A...%3A..." --session acct.json okgram import @cookies.txt --session acct.json # cookie file / EditThisCookie JSON echo "$SID" | okgram import - --session acct.json # from stdin # 诊断 WHY session 处于风险中 (region/routing/device/TLS 矛盾) okgram doctor --session acct.json --online # --online also checks egress IP okgram whoami --session acct.json okgram warmup --session acct.json # replay cold-start, re-save okgram feed --session acct.json okgram user instagram --session acct.json okgram geo --save --session acct.json # detect + pin region okgram session show --session acct.json # masked summary okgram repl --session acct.json # interactive shell, `cl` bound ``` 如果浏览器的 `sessionid` 在移动模式下仍然被封禁,请切换到 保持源一致性的 Web 模式: ``` okgram import "" --mode web --session acct.json ``` `okgram doctor` 是找出具体问题的最快方法 — 它会打印每一项 检查(区域、区号、时区、EU-DC、`X-MID`、`IG-U-RUR`、`www-claim`、 设备、传输方式,以及带有 `--online` 参数时的出口 IP 区域 + 实时 TLS/HTTP-2 指纹),并以 `OK / WARN / FAIL` 的形式显示及修复方法。 ## 硬核功能层(频率限制器 · 出口防护 · 指纹证明 · 账号金库) 专为严肃的、多账号使用提供的四个可选子系统: **1. 频率限制器 — 阻止 `feedback_required` / 操作封禁。** 操作频率是 IG 监控的另一个维度。限制器强制执行类似人类的单次操作上限 (针对点赞 / 关注 / 私信等的每小时 + 每天上限)、随机化的思考时间、 可选的休眠窗口,以及当 IG 返回 `feedback_required` 时自动进行冷却退避。读取操作永远不会被限制;计数值会持久化保存在 session 包中。 ``` cl = InstagramAPI(device_seed="acct", govern=True) # or cl.enable_governor(mode="raise") cl.media_like(media_id) # gated: paced + counted; raises/sleeps at the cap ``` **2. 出口防护 — 阻止瞬间触发挑战的 IP 切换。** 在执行操作之前, 验证出口 IP 的区域是否仍与 session 匹配;如果发生偏移,它会重新同步 (或引发异常),而不是让 IG 看到突然的国家变化。 ``` cl.guard_egress(policy="resync") # 'resync' | 'raise' | 'warn' ``` 请求层还会进行 **智能重试**:它会遵循 IG 的 `Retry-After` header, 而不是盲目地固定休眠,并且永远不会重试被操作封禁的请求。 **3. 指纹证明 — 测量实际离开 socket 的数据。** ``` okgram fingerprint --session acct.json # -> JA3 hash, JA4, HTTP/2 Akamai fingerprint, negotiated TLS, UA IG 看到, # 以及判定: PHONE-GRADE (OkHttp/h2) / BROWSER-GRADE / WEAK (Python/h1) ``` ``` print(cl.fingerprint()["verdict"]) ``` **4. 多账号金库 — 每个账号配备一个设备 + 一个代理 + 一个身份, 静态加密存储。** ``` okgram accounts add alice "" --proxy http://u:p@host:port --bootstrap \ --store ./vault --password "secret" okgram accounts list --store ./vault --password "secret" okgram accounts use alice --store ./vault --password "secret" --online ``` ``` from okgram import SessionStore vault = SessionStore("./vault", password="secret") # AES-GCM (PBKDF2) at rest vault.add("alice", "", proxy="http://u:p@host:port", bootstrap=True) cl = vault.open("alice") # device + routing + proxy restored ``` ## 快速开始 ``` from okgram import InstagramAPI from okgram.exceptions import TwoFactorRequired, ChallengeRequired, BadPassword cl = InstagramAPI( device_seed="myusername", # bind a stable device per account (important! don't randomize it every time) locale="th_TH", country="TH", country_code=66, timezone_offset=25200, delay_range=(1.0, 3.0), # random delay to avoid rate-limiting (None = disabled) ) try: cl.login("myusername", "mypassword") except TwoFactorRequired: code = input("Enter the 6-digit 2FA code: ") cl.two_factor_login(code) except ChallengeRequired: cl.challenge_resolve(choice=1) # 1=Email, 0=SMS cl.challenge_submit_code(input("Enter the code you received: ")) except BadPassword: print("Wrong password") # 保存 session 供下次使用 (这样你就无需频繁登录 = 更少的 flags) cl.dump_settings("session.json") ``` 下一次: ``` cl = InstagramAPI(device_seed="myusername") cl.load_settings("session.json") # restore the same device + token + cookies cl.login("myusername", "mypassword") # reuse the existing token if it hasn't expired ``` 或者使用现有的 `sessionid` 登录: ``` cl.login_by_sessionid("xxxxxxxxxxxxxx%3Ayyyyyyy%3A...") ``` ## 真实世界使用示例 ``` # --- Profile / users --- me = cl.get_current_user() user = cl.user_info_by_username_v1("instagram") uid = cl.username_to_user_id("instagram") cl.set_biography("Hello from the API 🐍") cl.account_set_private() # --- Following / followers --- cl.follow(uid) cl.unfollow(uid) followers = cl.user_followers(uid, amount=200) # paginates automatically following = cl.user_following(uid, amount=0) # 0 = all cl.mute_stories(uid) cl.block(uid); cl.unblock(uid) # --- Media / posts --- m = cl.media_info("3123456789_17841400000000000") cl.media_like(m["pk"]); cl.media_unlike(m["pk"]) cl.media_save(m["pk"]) cl.media_comment(m["pk"], "So cool!") comments = cl.media_comments(m["pk"]) cl.media_edit(m["pk"], "Edited caption") cl.media_delete(m["pk"]) # --- Feeds --- timeline = cl.get_timeline_feed() posts = cl.user_medias(uid, amount=50) liked = cl.liked_medias(amount=20) saved = cl.saved_medias(amount=20) # --- Uploads --- cl.photo_upload("pic.jpg", caption="Posted from the API") cl.video_upload("clip.mp4", caption="video", thumbnail="thumb.jpg") cl.album_upload(["a.jpg", "b.jpg", "c.jpg"], caption="album") cl.photo_upload_to_story("story.jpg") cl.clip_upload("reel.mp4", caption="New reel") # --- Stories / highlights --- tray = cl.reels_tray() story = cl.user_stories(uid) viewers = cl.story_viewers(story_pk, amount=0) cl.highlight_create("Japan trip", media_ids=[...]) # --- Direct (messages) --- inbox = cl.direct_threads(amount=20) cl.direct_send_text("Hello there", user_ids=[uid]) cl.direct_send_photo("pic.jpg", user_ids=[uid]) cl.direct_send_media_share(m["pk"], user_ids=[uid]) recips = cl.direct_search("john") # --- Search / explore --- res = cl.fbsearch_topsearch("cat memes") users = cl.search_users("cat") tags = cl.search_hashtags("cat") explore = cl.explore_medias(amount=30) # --- Hashtags / places --- cl.hashtag_info("cats") top = cl.hashtag_medias_top("cats", amount=27) cl.hashtag_follow("cats") places = cl.fbsearch_places("Bangkok") loc = cl.location_info(location_pk) # --- Reels / clips --- reels = cl.user_clips(uid, amount=20) disc = cl.clips_discover() # --- Notifications / insights (business/creator accounts) --- news = cl.news_inbox() badge = cl.notification_badge() acc_in = cl.insights_account() md_in = cl.insights_media(m["pk"]) ``` 你始终可以在底层自行调用端点: ``` cl.private_request("users/123/info/") # GET cl.private_request("friendships/create/123/", data={...}) # POST (signed_body automatically) cl.public_request("users/web_profile_info/", params={"username": "instagram"}) ``` ## 完整方法目录 | Mixin | 数量 | 示例方法 | |---|---|---| | **AuthMixin** | 15 | `login`, `two_factor_login`, `challenge_resolve`, `challenge_submit_code`, `login_by_sessionid`, `relogin`, `logout`, `get_settings`/`set_settings`, `dump_settings`/`load_settings`, `encrypt_password`, `pre_login_flow` | | **AccountMixin** | 26 | `get_current_user`, `edit_profile`, `set_biography`, `set_username`, `set_email`, `set_phone_number`, `set_gender`, `change_password`, `change_profile_picture`, `account_set_private`/`account_set_public`, `enable_totp_two_factor`, `set_account_type`, `account_security_info` | | **UserMixin** | 31 | `user_info`, `user_info_by_username_v1`, `web_profile_info`, `username_to_user_id`, `user_id_to_username`, `user_followers`, `user_following`, `search_users`, `user_similar_accounts`, `user_mutual_followers`, `usertag_medias` | | **FriendshipMixin** | 29 | `follow`, `unfollow`, `friendship_show`/`show_many`, `user_followers_page`, `user_following_page`, `pending_requests`, `approve_pending`/`reject_pending`, `remove_follower`, `block`/`unblock`, `mute_posts`/`mute_stories`, `restrict`/`unrestrict` | | **MediaMixin** | 26 | `media_info`, `media_info_by_code`/`by_url`, `media_like`/`unlike`, `media_save`/`unsave`, `media_delete`, `media_edit`, `media_likers`, `media_archive`/`unarchive`, `media_seen`, `media_pk_from_code`/`from_url`, `media_oembed` | | **CommentMixin** | 17 | `media_comment`, `media_comments`, `reply_to_comment`, `comment_delete`/`bulk_delete`, `comment_like`/`unlike`, `comment_pin`/`unpin`, `comment_likers`, `comment_replies`, `enable_comments`/`disable_comments` | | **FeedMixin** | 16 | `get_timeline_feed`, `user_medias`, `user_feed_page`, `liked_medias`, `saved_medias`, `collection_medias`, `reels_tray`, `popular_feed`, `my_medias` | | **UploadMixin** | 8 | `photo_upload`, `video_upload`, `album_upload`, `photo_rupload`, `video_rupload`, `photo_configure`, `video_configure`, `change_profile_picture` | | **StoryMixin** | 23 | `user_stories`, `reels_tray`, `story_viewers`, `story_seen`, `story_like`/`unlike`, `story_vote_poll`, `story_vote_slider`, `story_answer_quiz`, `highlight_create`/`edit`/`delete`, `highlight_info`, `user_highlights` | | **ClipsMixin** | 21 | `user_clips`, `clips_discover`, `clips_by_music`, `clip_upload`, `clip_info`, `clip_like`/`unlike`, `clip_comment`, `music_search`, `igtv_upload`, `igtv_channel` | | **DirectMixin** | 35 | `direct_threads`, `direct_thread`, `direct_send_text`/`link`/`photo`/`media_share`/`profile`/`hashtag`/`like`, `direct_mark_seen`, `direct_search`, `direct_thread_mute`/`hide`/`approve/`leave`/`add_users`, `direct_presence` | | **HashtagMixin** | 12 | `hashtag_info`, `hashtag_medias_top`/`recent`, `hashtag_follow`/`unfollow`, `hashtags_followed`, `hashtag_related`, `hashtag_story` | | **LocationMixin** | 11 | `location_search`, `location_info`, `location_medias_top`/`recent`, `fbsearch_places`, `location_related`, `location_story` | | **SearchMixin** | 17 | `fbsearch_topsearch`, `search_users`, `search_hashtags`, `search_places`, `explore_medias`, `explore_feed`, `suggested_users`, `discover_chaining`, `recent_searches`, `register_recent_search_click` | | **CollectionMixin** | 13 | `collections`, `collection_create`, `collection_add_media`, `collection_remove_media`, `collection_edit_name`, `collection_delete`, `collection_medias`, `saved_medias` | | **InsightsMixin** | 16 | `insights_account`, `insights_media`, `insights_story`, `insights_media_feed_all`, `media_engagement`/`impressions`/`reach`/`saves`, `account_reach`/`impressions` *(需要专业账号)* | | **LiveMixin** | 23 | `live_create`, `live_start`, `live_end`, `live_info`, `live_comment`/`comments`, `live_like`, `live_viewers`/`viewer_count`, `live_heartbeat`, `live_pin_comment`, `live_enable_comments`/`disable_comments` | | **NotificationMixin** | 17 | `news_inbox`, `news_following`, `notification_badge`, `activity_count`, `direct_unread_count`, `mark_news_seen`, `push_register`/`unregister`, `notification_settings` | 查看完整的方法列表: ``` import inspect from okgram import InstagramAPI cl = InstagramAPI() print([m for m in dir(cl) if not m.startswith("_") and callable(getattr(cl, m))]) ``` ## 项目结构 ``` okgram/ ├── __init__.py # exports InstagramAPI, Device, GeoProfile, geo/doctor/behaviors/live_config ├── __main__.py # `python -m okgram` -> CLI ├── cli.py # the `okgram` command (import/doctor/geo/whoami/warmup/feed/user/session/repl) ├── client.py # main InstagramAPI class (combines all mixins) + bootstrap/sync_geo/sync_config ├── config.py # constants + geo tables (calling codes, EU-DC, providers) + mode/live-sync config ├── geo.py # egress-IP geo auto-detection -> consistent region profile (every country) ├── live_config.py # pull bloks/public-key/routing live from launcher+qe sync ├── behaviors.py # cold-start sequence + X-IG-Nav-Chain builder + human pacing ├── doctor.py # session-identity consistency diagnostics (the bounce finder) ├── limits.py # rate governor: per-action caps + think-time + sleep window + cooldown ├── guard.py # egress-IP consistency check + Retry-After-aware smart retry ├── fingerprint.py # live JA3/JA4/HTTP-2 fingerprint probe + grade ├── store.py # multi-account vault: proxy-per-account + AES-GCM encryption ├── device.py # simulates an Android device + builds the User-Agent (deterministic per seed) ├── exceptions.py # exception hierarchy + maps IG errors ├── utils.py # sign body, uuid, media pk<->code, helpers ├── requirements.txt └── mixins/ ├── private.py # ⭐ core: private_request / public_request / graphql_request + headers + retry ├── auth.py # login / 2FA / challenge / session ├── account.py user.py friendship.py media.py comment.py feed.py ├── upload.py story.py clips.py direct.py hashtag.py location.py └── search.py collection.py insights.py live.py notification.py ``` **架构:**每个类别都是一个独立的 *mixin* 文件,`InstagramAPI` 将它们全部继承在一起。 每个 mixin 都通过 `mixins/private.py` 中的 `self.private_request(...)` 调用后端,该文件负责处理: - 添加完整的 `X-IG-*` / `X-Bloks-*` / `Authorization` header 集 - 自动将 body 包装为 `signed_body=SIGNATURE.`(现代未签名格式) - 从响应 header 更新 token/claim/mid - 将错误 JSON 转换为异常 + 重试 + 随机延迟 ## 错误处理 ``` from okgram.exceptions import ( LoginRequired, ChallengeRequired, TwoFactorRequired, BadPassword, FeedbackRequired, PleaseWaitFewMinutes, ClientThrottledError, MediaNotFound, UserNotFound, PrivateAccount, ClientError, ) ``` - `LoginRequired` → session 已过期,调用 `cl.relogin()` - `ChallengeRequired` → 调用 `cl.challenge_resolve()`,然后调用 `cl.challenge_submit_code(code)` - `FeedbackRequired` / `PleaseWaitFewMinutes` → 你遇到了操作封禁,请先休息一下 - `ClientThrottledError` (429) → 请求过于频繁,请等待并放慢速度 ## 让它“真正起效”并降低被封禁几率的提示 1. **使用 `bootstrap()`(或 `okgram import`)** 而不是仅使用简单的 `login_by_sessionid` — 它可以对齐地理位置、拉取实时配置并进行预热,从而使最初的请求保持一致 2. **在遇到封禁时运行 `okgram doctor --online`** — 它会指出具体的矛盾之处(区域/路由/设备/IP),而不是盲目猜测 3. **为每个账号使用相同的 `device_seed`**,并始终使用 `dump_settings`/`load_settings` — 保存的包现在包含 `IG-U-RUR`/mid/claim/geo,因此重新加载可以重现 IG 上次看到的准确身份 4. **让地理位置自动同步**(`auto_geo=True`,默认值)以将 `country`/`timezone`/EU-DC 对齐到你的真实 IP — 或者手动设置它们以使其匹配。不要混合使用(例如在泰国 IP 上使用 `country="US"`) 5. **启用 `delay_range`**,不要连续不断地发送请求 6. **使出口 IP 与账号的区域相匹配。** 账号所在国家/地区的干净 **住宅** IP(甚至是你的家庭网络)是理想的;通过相同国家/地区的代理路由服务器:`InstagramAPI(proxy="http://user:pass@host:port")` — 地理位置自动同步会通过代理进行检测 7. **浏览器的 `sessionid` 是一个 Web session** — 如果移动模式被封禁,请使用 `mode="web"`(保持源一致性) 8. **新账号 / 刚刚更改了 IP 的账号**通常会面临验证挑战 — 这是正常的 9. **App 版本可能会随着时间推移被拒绝** → 在 `config.py` 中更新 `APP_VERSION`/`VERSION_CODE` (或者使用 `cl.set_user_agent(app_version=..., version_code=...)`)以匹配更新的版本对 ## 来源 - 目标/主机/app-id 是从 **Instagram Lite 516.0.0.8.103** 的反编译中提取的(`X-IG-App-ID: 567067343352427`,主机 `i.instagram.com` / `iglite-z.instagram.com`,`SIGNATURE` 风格的签名) - 端点集合是 Instagram Private API `v1`,与 Instagram Android/Lite App 使用的相同 ## 主题 Instagram API · Instagram Private API · instagram-private-api · instagrapi alternative · Instagram bot · Instagram automation · Python · OkHttp · HTTP/2 · JA3 · JA4 · TLS fingerprint · TLS impersonation · tls-client · curl_cffi · anti-detection · device fingerprint · sessionid login · cookie login · IG-U-RUR · proxy · rate limiter · multi-account · reverse engineering · CLI
标签:Instagram API, Python, 云资产清单, 反封锁, 无后门, 网络请求库, 逆向工具, 逆向工程