我向 Instagram 索取 NASA 最新 12 條 Reels,結果 9 條由其他帳戶發佈
I Asked Instagram for NASA's 12 Newest Reels. Nine Belonged to Other Accounts
一次登出狀態下的 Instagram 抓取測試發現,NASA 個人檔案最新 12 條 Reels 中,只有 3 條由 NASA 發佈,其餘 9 條來自其他帳戶。從個人檔案讀取可取得觀看次數,但以 Reel 連結讀取時觀看次數缺失,Actor 會改用讚好數比較,令相同影片的離羣判定不同。分析時不應混用兩種輸入方式。
I run a visa agency in Bali. The half of my week that is not visas goes into Apify Actors, and one of them reads short vertical video: give it Reel, TikTok or Shorts links — or a whole profile — and it returns one flat row per video with the transcript, the text burned into the picture, and the engagement numbers the platform showed.
Profile mode is what people buy it for: watch this creator, transcribe whatever they post. It is also where Instagram hands you a different dataset than the one you asked for, in two separate ways. I measured both on 18 October 2026, and the second one changes which videos your pipeline calls viral.
The setup
One run, logged out, no cookies, no official API: profiles instagram.com/nasa/ and instagram.com/natgeo/, twelve newest Reels each, on-screen text off. 24 rows, 24 transcribed, zero failures, 59 seconds end to end.
Then a second run, 19 seconds, with the ten own-authored Reels of one of those profiles pasted in as plain links. Same videos, different input shape.
The Reels tab is a grid, not an authorship list
Here is who actually wrote the twelve Reels that came back for @nasa:
nasa 3
astro_jessica 2
nasajohnson 2
eaglescheer 1
ravens 1
nasaadmin 1
astro_anil 1
nasaaero 1
Three of twelve. The rest are other accounts' Reels sitting on NASA's grid — other NASA centres, individual astronauts, two sports teams. One is from the Philadelphia Eagles cheerleaders, captioned An inspiration to us all, thank you for stopping by @astro_christina 💚, 864,791 views. A real Reel on a public page, correctly returned. Just not NASA's.
@natgeo is tidier and still not clean: ten of twelve are natgeo, one is natgeofamily, one is 911onabc — a Disney sibling show.
The mechanism is collaborator posts: a co-authored Reel is served on both profiles, and the owner field names whoever posted it. The page hands a logged-out visitor the grid as rendered — it has no concept of "only posts this account authored", and neither does any scraper reading it.
So if your question is how often does this creator post and what do they say, the profile count is not the answer. The field you need is already in the row:
mine = [r for r in rows if r.get("author") == "nasa"]
Which sounds obvious until you see what it costs downstream.
The baseline that never formed
Every row carries vsAuthorMedian: how many times a video beat its own author's usual, computed from the other videos by that author in the same run. At least three peers are required, otherwise the field is null — a ratio computed from one neighbour is a coin flip wearing a decimal point.
For @natgeo the ten own-authored Reels gave each other a baseline and the run flagged the outliers. For @nasa, three own Reels out of twelve, the baseline never formed: vsAuthorMedian, authorMedian and isOutlier came back null on all twelve rows. Twelve clean transcripts, no virality signal at all.
That is the right behaviour — pooling eight accounts into one median produces a number that means nothing — but it is not what you expect from "I asked for twelve videos". On a collab-heavy account you would have to raise the ask until twelve own-authored Reels fit inside it, and logged out you cannot: twelve is the whole ceiling.
Ten identical videos, two different virality answers
Now the second finding, and the one I would put on a sticker.
Instagram shows view counts on the Reels tab of a public profile. It does not show them on a single Reel page to a logged-out visitor. Same ten @natgeo Reels, run both ways:
| videoId | views (profile run) | views (link run) | likes |
|---|---|---|---|
| DemLxMGgoL_ | 4,072,300 | null |
205,239 |
| Dec1lmtgGYk | 642,521 | null |
51,232 |
| DeobYzjga9x | 334,391 | null |
96,650 |
| DehZj9wggt0 | 286,821 | null |
49,146 |
| DeckcQnA23l | 238,557 | null |
21,594 |
| Delg3cUktih | 189,002 | null |
10,379 |
| DeeUUHNAqQj | 188,567 | null |
14,570 |
| Del2uq1gnwg | 178,700 | null |
17,062 |
| DefFZgggApb | 172,808 | null |
43,590 |
| DecPSQfoaRe | 110,213 | null |
21,124 |
Likes survive both runs and agree to within 549 on the noisiest row — they are live counters, so small drift between two runs minutes apart is expected. Views simply are not in the single-Reel payload.
The Actor handles that by falling back: when every video in an author group has views it compares on views, otherwise on likes, and vsAuthorBasis says which. Honest, and still not interchangeable. Ranking those ten Reels by likes instead of views gives:
- 11 of 45 pairs in the wrong order (Spearman ρ = 0.71)
- like-to-view ratio from 5.04% to 28.90% across the same ten videos of one account — a 5.7× spread
- a different set of outliers
That last one is the part that reaches your dashboard. At the 3× threshold:
basis = views -> outliers: DemLxMGgoL_ (21.55x), Dec1lmtgGYk (3.40x)
basis = likes -> outliers: DemLxMGgoL_ (9.51x), DeobYzjga9x (4.50x)
One video in, one video out, on identical input videos. Dec1lmtgGYk pulled 642k views on a 7.97% like rate — broad reach, ordinary engagement. DeobYzjga9x got a third of that reach at a 28.90% like rate — a small, very warm audience. Views call the first a breakout, likes call the second. Both are defensible; neither substitutes for the other, and if half your rows arrived by link and half by profile, your "top videos" list is mixing two scales.
Practical rule: do not mix input shapes inside one analysis. Pull by profile when you need reach; if a Reel has to arrive by link, label its vsAuthorMedian as an engagement figure — vsAuthorBasis is in the row precisely so you can.
The twelve-item ceiling is a scheduling constraint
Instagram's logged-out Reels tab renders twelve items. That is not a parameter the Actor could raise; it is the page. Which means how often you need to run is set by how fast the creator fills twelve slots.
In my two runs the twelve newest Reels covered:
-
@nasa— 14 September to 10 October, 26 days -
@natgeo— 13 October to 18 October, 5 days
A weekly watch on @natgeo would have silently missed Reels; on @nasa it would have been comfortable. Same ceiling, 5× difference in how long the window lasts. Measure the span of your first run, set the schedule to a fraction of it, and turn on "only videos not processed before" so the overlap costs nothing — already-seen videos are skipped before download and not billed.
What the whole exercise cost
24 Reels transcribed, speech recognition on, on-screen text off: $0.2422 total, per-row from $0.0028 to $0.0364. The cheap rows are the silent ones: four of the ten @natgeo Reels had no speech, came back with transcriptSource: no-speech, and were billed for the video event only, no audio charge. The expensive row was 236 seconds long. Re-running the ten Reels as links cost $0.0658.
Calling it is a POST and a read:
import requests, statistics
TOKEN = "<your apify token>"
rows = requests.post(
"https://api.apify.com/v2/acts/lergassy~instagram-reels-transcript-scraper"
"/run-sync-get-dataset-items",
params={"token": TOKEN},
json={
"profiles": ["https://www.instagram.com/natgeo/"],
"resultsLimitPerProfile": 12,
"includeOnScreenText": False,
"onlyNewVideos": True,
"watchlistName": "natgeo-weekly",
},
).json()
mine = [r for r in rows if r.get("type") == "reel" and r.get("author") == "natgeo"]
print(len(rows), "rows ->", len(mine), "authored by the profile")
basis = {r.get("vsAuthorBasis") for r in mine}
print("comparison basis:", basis) # {'views'} by profile, {'likes'} by link
span = sorted(r["postedAt"] for r in mine)
print("window:", span[0], "->", span[-1]) # set your schedule inside this
Three lines of hygiene, in this order, before anything aggregates: filter on author, assert a single vsAuthorBasis, read the date span. Full field list and the input form: Instagram Reels Transcript Scraper.
When this is the wrong tool
If you need more than twelve Reels of a profile in one go, this is not it — and no logged-out scraper is, because the page stops there. Older Reels need their own links, which drops the views again. If you need historical view counts, also stop: Instagram reports a live counter, so a time series only exists if you start snapshotting now. And if your question is purely what was said, skip profile mode and paste links — authorship and reach stop mattering, and the whole problem above goes away.
The general lesson is not about Instagram. A profile endpoint answers "what is displayed on this page", and you read it as "what this account produced". Those two differ by nine rows out of twelve on a heavily collaborating account, and the field that tells you so is sitting in the response, ignored.
來源:DEV Community · dev.to