Skip to content

Conversation

@SamuMazzi
Copy link
Contributor

@SamuMazzi SamuMazzi commented Mar 13, 2025

Hello! This PR aims to fix the problem that caused many and many users to be unable to download anything, either profiles and posts.

This problem affected a lot of us, but in the end, there was simply some backend change made by Instagram, so it was needed to change some parameters and adapt to the new responses, and now some things like _convert_iphone_carousel are not even needed anymore.

Actually there are way more incompatible changes (i.e. logged in user doesn't work, neither the fetching of users by their id) so someone should take care also of that.

  • Is it just a proof of concept? No
  • Is the documentation updated (if appropriate)? No
  • Do you consider it ready to be merged or is it a draft? Ready
  • Can we help you at some point? No

I think I made all the changes correctly, but a deeper look from a more experienced "instaloader developer" would be appreciated, thanks!

Fixes #2532, #2528, #2307, #2517, #2501, #2511, #2508

@anaacaren
Copy link

Hi! I've just ran your changes, it works like a charm!! Thank you :)

@kakaroto
Copy link

I tried your branch as well, and it works great. Though it seems that I still get the 401 unauthorized errors when it loads the session from file, so it asks me for the password every time.

Loaded session from C:\Users\kakaroto\AppData\Local\Instaloader\session-XXXXX.
JSON Query to graphql/query: 401 Unauthorized - "fail" status, message "Please wait a few minutes before you try again." when accessing https://www.instagram.com/graphql/query?query_hash=d6f4427fbe92d846298cf93df0b937d3&variables=%7B%7D [retrying; skip with ^C]
JSON Query to graphql/query: 401 Unauthorized - "fail" status, message "Please wait a few minutes before you try again." when accessing https://www.instagram.com/graphql/query?query_hash=d6f4427fbe92d846298cf93df0b937d3&variables=%7B%7D [retrying; skip with ^C]
Error when checking if logged in: JSON Query to graphql/query: 401 Unauthorized - "fail" status, message "Please wait a few minutes before you try again." when accessing https://www.instagram.com/graphql/query?query_hash=d6f4427fbe92d846298cf93df0b937d3&variables=%7B%7D
Enter Instagram password for XXXXX:

Not sure if it's related to the same core issue you sent the PR for, or if it's an unrelated issue.

@SamuMazzi
Copy link
Contributor Author

@kakaroto yeah I know, this PR doesn't aim to solve that problem yet... I'm not really using that functionality so I don't know if/when I'll fix it, sorry!

@kakaroto
Copy link

@kakaroto yeah I know, this PR doesn't aim to solve that problem yet... I'm not really using that functionality so I don't know if/when I'll fix it, sorry!

No worries! I'll try to give it a poke at some point if I get the time. Thanks for your changes, it helps already!

@jaybiirds
Copy link

I forked the repository and pushed your commit and it seemed to work great, but after 96 posts downloaded, I got the same JSON Query to graphql/query: 401 Unauthorized - "fail" status, message "Please wait a few minutes before you try again." error. None of my JSON files are readable either, unsure if I did something wrong or if picking an account with a lot of posts had something to do with it.

@xathian
Copy link

xathian commented Mar 22, 2025

I forked the repository and pushed your commit and it seemed to work great, but after 96 posts downloaded, I got the same JSON Query to graphql/query: 401 Unauthorized - "fail" status, message "Please wait a few minutes before you try again." error. None of my JSON files are readable either, unsure if I did something wrong or if picking an account with a lot of posts had something to do with it.

Unfortunately I can't say for certain but I am pretty sure I downloaded an account with over 96 posts last week just fine using these fixes.

@xathian
Copy link

xathian commented Mar 23, 2025

This PR was working perfect for me yesterday but now I'm getting this error again:

JSON Query to api/v1/users/web_profile_info/?username=username_username: 401 Unauthorized - "fail" status, message "Please wait a few minutes before you try again." when accessing https://i.instagram.com/api/v1/users/web_profile_info/?username=username_username [retrying; skip with ^C]

Can't download any posts at all. After I run it, it buffers for a few seconds, sends two copies of that error, then throws this error:

Error accessing Instagram profile: JSON Query to api/v1/users/web_profile_info/?username=username_username: 401 Unauthorized - "fail" status, message "Please wait a few minutes before you try again." when accessing https://i.instagram.com/api/v1/users/web_profile_info/?username=username_username

Anyone else having this issue?

Nope, just ran an update on an account and it grabbed 4 missing posts just fine

@Plaoo
Copy link

Plaoo commented Mar 24, 2025

Works, thank you

@latinokodi
Copy link

Newbie question here, I've been trying to use this PR but I don't think I really know how to, could you be so kind and provide the commands needed to download this corrected version?

@SamuMazzi
Copy link
Contributor Author

Hi @latinokodi, I don't know if there are better ways to do this but what I would do is cloning the repo from which I've created the modifications and then install it in your project

git clone https://github.com/SamuMazzi/instaloader.git
cd path/to/your_project
pip install path/to/instaloader

Hope it can be helpful!

@willianbriotto
Copy link

Works, thank you

@latinokodi
Copy link

Works, thank you

How did you make it work?

@xcaptain
Copy link

no longer works

@gabriele2605
Copy link

Now needs at least the login even for open profiles

Exception has occurred: LoginRequiredException
Redirected to login page. Use --login.

@IgorArnaut
Copy link

It stopped working. Damn Meta.

@VolpiGiuliano
Copy link

Hi @latinokodi, I don't know if there are better ways to do this but what I would do is cloning the repo from which I've created the modifications and then install it in your project

git clone https://github.com/SamuMazzi/instaloader.git
cd path/to/your_project
pip install path/to/instaloader

Hope it can be helpful!

It works!!!

@aandergr
Copy link
Member

Thanks for the contribution — we’ll be happy to review it. Two observations upfront:

  • This PR changes the user agent, which in the past has affected the structure of returned data. Such a change is not without risk of breaking things. Therefore, this should be based on the upcoming/v4.15 branch, where related changes have already started.
  • from_iphone_struct() appears to no longer handle the structure we currently treat as iPhone-format. If there’s a new format, it should be handled in a separate constructor to avoid breaking existing functionality depending on from_iphone_struct().

Looking forward to the updated version.

@Speedy1991
Copy link

Hey @aandergr,
@SamuMazzi has already done the heavy lifting on this one 🎉.
Would you have a chance to help bring it over the finish line? There are already several installed forks with this fix, but since it’s quite an important bug, it would be great to have it addressed upstream.

If there’s already an upcoming/v4.15 branch in the works, maybe we could merge these changes into it so it’s part of the next release?

@SamuMazzi
Copy link
Contributor Author

@aandergr sorry for replying so late! Thank you for your response.. I think I did what you said but I'm not 100% so feel free to tell me what you think
(Also I took the freedom to update gitignore and change a small thing in the last commit, hope it's not a problem)

@ekalin
Copy link
Collaborator

ekalin commented Aug 28, 2025

The "new" iPhone struct actually looks like the old (non-iPhone) struct, created with the constructor.

@billbeans
Copy link

billbeans commented Sep 29, 2025

Hey, I tried your PR and I actually was able to download a profile for the first time in ages. The only thing I'm confused about is my terminal is littered with these error messages:

[ 2/48] **[REDACTED]**/2025-09-03_**-**-**_UTC_1.jpg download_pic(): Invalid URL '': No scheme supplied. Perhaps you meant https://? [retrying; skip with ^C]
download_pic(): Invalid URL '': No scheme supplied. Perhaps you meant https://? [retrying; skip with ^C]
Download <Post **[REDACTED]**> of **[REDACTED]**: download_pic(): Invalid URL '': No scheme supplied. Perhaps you meant https://?

Update: I tried another profile and now I'm suddenly not getting those errors. Weird

@billbeans
Copy link

billbeans commented Oct 30, 2025

Upon further usage, I've come to suspect that those errors are related to a change on Instagram's backend sometime around 2020. Older posts don't seem to yield those errors.

Seeing that the main branch still doesn't work for anonymous fetching, would you also be able to take a look at fetching reels highlights? They are completely unable to be scraped.

@aandergr
Copy link
Member

aandergr commented Nov 8, 2025

Hi. I had finally the chance to have a deeper look into this. Thanks for your patience and for sharing your work on this!

The staticmethod Post::from_new_iphone_struct is actually not needed. The structure that is returned is not a "new iphone structure", it is rather the classical structure that the Post constructor parses. So replacing the Post.from_new_iphone_struct() invocations with Post() seems the way to go.

It attempts to download sidecar node videos for sidecar nodes that are no videos. This is easily fixed by rewriting the if condition more careful in instaloader.py:748: if video_url and sidecar_node.is_video and self.download_videos. (update: there is a change that explicitly sets it to an empty string instead of None, this needs to be reverted)

The PR lists some unrelated commits and unrelated changes. Unfortunately we cannot merge it as is. It would help us a lot if you could rebase it properly to upcoming/v4.15 and also remove the unrelated changes. (update: we could change the base in the PR)

With these changes, downloading anonymously seems fixed for profiles.

@aandergr aandergr changed the base branch from master to upcoming/v4.15 November 8, 2025 17:17
@aandergr
Copy link
Member

aandergr commented Nov 8, 2025

It needs to be checked whether this change also works logged-in and downloads the same quality as before. If not, some of the changes need to be encapsulated in a check whether we are logged-in or anonymously.

Comment on lines 261 to 265
@classmethod
def from_new_iphone_struct(cls, context: InstaloaderContext, media: Dict[str, Any]):
"""Create a post from a given new_iphone_struct.
.. versionadded:: 4.15"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This classmethod is actually redundant; it seems the Post constructor can be invoked instead.

for node in media["carousel_media"]]}
return cls(context, fake_node, Profile.from_iphone_struct(context, media["user"]) if "user" in media else None)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated change; please remove.

Comment on lines 502 to 532
video_url=node['video_url'] if is_video else None)
video_url=str(node['video_url']) if is_video else "")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This triggers a broken sidecar node video downloading for every non-video sidecar node.

Comment on lines 1003 to 1004
metadata = self._context.get_iphone_json('api/v1/users/web_profile_info/',
params={'username': self.username})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change relevant?

.gitignore Outdated
Comment on lines 3 to 5
venv/
*.egg-info/
build/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is unrelated; I suggest to add those to your local .git/info/exclude to not have them listed as untracked files. (also see https://git-scm.com/docs/gitignore )

@billbeans
Copy link

Yes, I mentioned in my earlier comment that this branch can't download reels, but what I really meant was highlights - I had the terminology wrong. I find that using this branch for anonymous fetching of posts then logging in on the main branch to grab highlights is a good strategy, as it greatly reduces the amount of requests you're making on your account, lowering the chances of a ban. Of course, you don't get the full resolution content, but I think it's close enough.

@aandergr
Copy link
Member

aandergr commented Nov 8, 2025

We did some major cleanup on this PR: We removed the Post.from_new_iphone_struct. It was only used in Instaloader.get_location_posts and Hashtag.get_top_posts, where it did not fix the download, neither anonymously nor logged-in, and in Hashtag.get_posts, which is deprecated.

So the only significant change was in Profile.get_posts, which fixed the download for the anonymous case, but in return broke it for the logged-in case. We rewrote this change to affect the behavior only when not logged in.

The change in the unit test did not test any of the other changes.

@aandergr aandergr merged commit 6490878 into instaloader:upcoming/v4.15 Nov 8, 2025
8 checks passed
@SamuMazzi
Copy link
Contributor Author

Sorry for the late reply @aandergr, but thanks for the support and all those fixes :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

401 Unauthorized Error - "Please wait a few minutes before you try again."