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
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user