- Also uses the recently-introduced get_page_data query, rather than the
non-working web_profile_info.
- Stores (and reuses) this in a Profile._page_user field.
The NodeIterator is sometimes invocated with node wrappers that are heavy to
invocate, e.g. because they trigger requests. Storing the resulting item
besides the node allows to avoid those extra requests.
In the FrozenNodeIterator, the node is still saved, rather than the item.
Instagram now answers doc_id 28975909992013618 with 400 "feedback_required".
Use the query the web app currently sends for a profile's posts tab
(PolarisProfilePostsTabContentQuery_connection), doc_id 29104886249145907,
with its current relay provider variables.
(cherry picked from commit 804894a0b1, #2785)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The GraphQL query used so far now returns edge_web_feed_timeline: null, which
raised a TypeError. Page through api/v1/feed/timeline/ instead and convert its
media items (iPhone format).
Fixes#2556
- `InstaloaderContext.get_page_data()` loads a page as a logged-out visitor and returns the query results that the page embeds. Instagram only embeds them when the request looks like a page navigation, so the request sends the `Sec-Fetch-*` headers of one.
- `Profile.from_username()` reads the profile from its public page. Anonymously, `_normalize_profile_data()` completes the node.
- Logged in, `Profile.get_posts()` uses query `28975909992013618` (`PolarisProfilePostsTabContentQuery_connection`) with the variables that the web app sends. The response has the same shape as before.
When logged in, `from_username()` does not normalize the page's node. The page shows the profile to a logged-out visitor, so normalizing would set `followed_by_viewer` to `False`, and `download_profiles()` would refuse private profiles that the session follows. Instead, the GraphQL profile query in `_obtain_metadata()` fills in the missing fields when they are first read.