[ie/instagram] Detect when cookies are invalidated (#17126)

Thanks to @0xvd and @gamer191 for their research/testing

Closes #17124
Authored by: bashonly
This commit is contained in:
bashonly 2026-07-03 13:16:37 -05:00 committed by GitHub
parent ad9a6f25f6
commit ac4c955ea9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -3,6 +3,7 @@ import hashlib
import itertools import itertools
import json import json
import re import re
import urllib.parse
from .common import InfoExtractor from .common import InfoExtractor
from ..networking.exceptions import HTTPError from ..networking.exceptions import HTTPError
@ -42,15 +43,23 @@ def _id_to_pk(shortcode):
class InstagramBaseIE(InfoExtractor): class InstagramBaseIE(InfoExtractor):
_API_BASE_URL = 'https://i.instagram.com/api/v1' _API_BASE_URL = 'https://i.instagram.com/api/v1'
_BASE_URL = 'https://www.instagram.com/' _BASE_URL = 'https://www.instagram.com/'
_LOGIN_URL = 'https://www.instagram.com/accounts/login'
_APP_IDS = { _APP_IDS = {
'ios': '124024574287414', 'ios': '124024574287414',
'web': '936619743392459', # default 'web': '936619743392459', # default
} }
_AUTH_COOKIE_NAME = 'sessionid'
_COOKIE_DOMAINS = (
'i.instagram.com',
'.i.instagram.com',
'www.instagram.com',
'.www.instagram.com',
'instagram.com',
'.instagram.com',
)
@property @property
def _is_logged_in(self): def _is_logged_in(self):
return bool(self._get_cookies(self._BASE_URL).get('sessionid')) return bool(self._get_cookies(self._BASE_URL).get(self._AUTH_COOKIE_NAME))
@functools.cached_property @functools.cached_property
def _app_id(self): def _app_id(self):
@ -71,6 +80,10 @@ class InstagramBaseIE(InfoExtractor):
'Accept': '*/*', 'Accept': '*/*',
} }
@staticmethod
def _is_login_redirect(url):
return urllib.parse.urlparse(url).path.startswith('/accounts/login')
def _get_count(self, media, kind, *keys): def _get_count(self, media, kind, *keys):
return traverse_obj( return traverse_obj(
media, (kind, 'count'), *((f'edge_media_{key}', 'count') for key in keys), media, (kind, 'count'), *((f'edge_media_{key}', 'count') for key in keys),
@ -397,6 +410,7 @@ class InstagramIE(InstagramBaseIE):
def _real_initialize(self): def _real_initialize(self):
if self._is_logged_in: if self._is_logged_in:
self.write_debug('Found Instagram account cookies')
return return
if not self._lsd_token: if not self._lsd_token:
webpage = self._download_webpage(self._BASE_URL, None, 'Setting up session', impersonate=True) webpage = self._download_webpage(self._BASE_URL, None, 'Setting up session', impersonate=True)
@ -411,10 +425,21 @@ class InstagramIE(InstagramBaseIE):
media_id = str(_id_to_pk(video_id)) media_id = str(_id_to_pk(video_id))
if self._is_logged_in: if self._is_logged_in:
return self._extract_product(self._download_json( try:
f'{self._API_BASE_URL}/media/{media_id}/info/', video_id, return self._extract_product(self._download_json(
'Downloading video info', 'Video info extraction failed', f'{self._API_BASE_URL}/media/{media_id}/info/', video_id,
impersonate=self._is_web_app, headers=self._api_headers)['items'][0]) 'Downloading video info', 'Video info extraction failed',
impersonate=self._is_web_app, headers=self._api_headers)['items'][0])
except ExtractorError as e:
if not (isinstance(e.cause, HTTPError) and self._is_login_redirect(e.cause.response.url)):
raise
self.report_warning('The provided Instagram account cookies are no longer valid')
# XXX: With curl-cffi, the error response may not invalidate the cookie in our jar
for domain in self._COOKIE_DOMAINS:
self.cookiejar.clear(domain=domain, path='/', name=self._AUTH_COOKIE_NAME)
# Re-initialize to set lsd token for logged-out extraction
self._real_initialize()
api_check = self._download_json( api_check = self._download_json(
f'{self._API_BASE_URL}/web/get_ruling_for_content/', video_id, f'{self._API_BASE_URL}/web/get_ruling_for_content/', video_id,
@ -466,7 +491,7 @@ class InstagramIE(InstagramBaseIE):
webpage, urlh = self._download_webpage_handle( webpage, urlh = self._download_webpage_handle(
f'https://www.instagram.com/p/{video_id}', video_id) f'https://www.instagram.com/p/{video_id}', video_id)
if urlh.url.startswith(self._LOGIN_URL): if self._is_login_redirect(urlh.url):
self.raise_login_required( self.raise_login_required(
'The webpage request was redirected to the login page. ' 'The webpage request was redirected to the login page. '
'You have exceeded the rate-limit for accessing posts anonymously') 'You have exceeded the rate-limit for accessing posts anonymously')