From b1aa0eb6f591e03af8b30db5a3cbb7fd6d9a1f14 Mon Sep 17 00:00:00 2001 From: smolkik-code Date: Wed, 17 Jun 2026 11:37:53 +0700 Subject: [PATCH] fix: support cookie-based auth, direct login often blocked by Instagram - Try instaloader session file first - Then cookies.txt (Mozilla format from browser extension) - Then cookies.json (from browser extensions) - Direct login as last resort with clear instructions --- instagram_monitor.py | 74 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 10 deletions(-) diff --git a/instagram_monitor.py b/instagram_monitor.py index 5c039ad..f5a8662 100644 --- a/instagram_monitor.py +++ b/instagram_monitor.py @@ -1,3 +1,4 @@ +import http.cookiejar import json import os import shutil @@ -40,19 +41,72 @@ class InstagramMonitor: json.dump(self._state, f, indent=2) def login(self) -> bool: - try: - if self._session_path.exists(): + # Method 1: load existing instaloader session file + if self._session_path.exists(): + try: self.loader.load_session_from_file(config.instagram_username, str(self._session_path)) - logger.info("Session loaded from file") + logger.info("Session loaded from instaloader session file") return True + except Exception as e: + logger.warning(f"Session file invalid: {e}") - self.loader.login(config.instagram_username, config.instagram_password) - self.loader.save_session_to_file(str(self._session_path)) - logger.info("Logged in and session saved") - return True - except Exception as e: - logger.error(f"Login failed: {e}") - return False + # Method 2: load cookies.txt exported from browser + cookies_path = Path(config.download_dir) / "cookies.txt" + if cookies_path.exists(): + try: + self._load_cookies_from_txt(cookies_path) + logger.info("Session loaded from cookies.txt") + return True + except Exception as e: + logger.warning(f"cookies.txt invalid: {e}") + + # Method 3: load cookies.json exported from browser extension + cookies_json_path = Path(config.download_dir) / "cookies.json" + if cookies_json_path.exists(): + try: + self._load_cookies_from_json(cookies_json_path) + logger.info("Session loaded from cookies.json") + return True + except Exception as e: + logger.warning(f"cookies.json invalid: {e}") + + # Method 4: direct login (often blocked by Instagram now) + if config.instagram_password: + try: + self.loader.login(config.instagram_username, config.instagram_password) + self.loader.save_session_to_file(str(self._session_path)) + logger.info("Logged in via direct login and session saved") + return True + except Exception as e: + logger.error(f"Direct login failed: {e}") + logger.info( + "Use cookies.txt or cookies.json instead. " + "Export from browser: install 'Get cookies.txt LOCALLY' extension, " + "go to instagram.com, export, put file in /data/downloads/cookies.txt" + ) + return False + + logger.error("No valid session or credentials found") + return False + + def _load_cookies_from_txt(self, path: Path) -> None: + cj = http.cookiejar.MozillaCookieJar(str(path)) + cj.load(ignore_discard=True, ignore_expires=True) + self.loader.context._session.cookies.update(cj) + # Verify session works + instaloader.Profile.from_username(self.loader.context, config.instagram_username) + + def _load_cookies_from_json(self, path: Path) -> None: + with open(path) as f: + cookies = json.load(f) + for cookie in cookies: + self.loader.context._session.cookies.set( + cookie["name"], + cookie["value"], + domain=cookie.get("domain", ".instagram.com"), + path=cookie.get("path", "/"), + ) + instaloader.Profile.from_username(self.loader.context, config.instagram_username) def _get_profile_posts(self, username: str) -> list[instaloader.Post]: try: