class BaseBot: def __init__(self, username: str, password: str, loader_kwargs: dict = None, **kwargs): self.session_file = kwargs.get('session_path', f'./{username}_session.pickle') self.loader = Instaloader(**(loader_kwargs or dict())) self.context = self.loader.context safe_login(self.loader, username, password, self.session_file) self.insta = TlaskyInsta(self.loader) self.logger = self.insta.logger self.scheduler = Scheduler() def on_start(self): """ Here you can load your stuff. """ pass def loop(self): """ Main bot function. """ def on_exit(self): """ Here you can save your stuff. """ self.loader.save_session_to_file(self.session_file)
class Insta: def __init__(self): self.loader = Instaloader() try: self.loader.load_session_from_file(USER, f'session-{USER}') except FileNotFoundError: self.loader.context.log( "Session file does not exist yet - Logging in.") if not self.loader.context.is_logged_in: try: self.loader.login(USER, PASSWORD) except TwoFactorAuthRequiredException: self.loader.two_factor_login(input('Code: ')) self.loader.save_session_to_file(f'session-{USER}') if self.loader.context.is_logged_in: self.loader.context.log('Logged in.', end='\n' * 2) def get_unfollowers(self, user): self.loader.context.log( 'Getting list of accounts i\'m subscribed to but not subscribed to me:' ) profile = Profile.from_username(self.loader.context, user) followers = profile.get_followers() followees = profile.get_followees() unfollowers = set(followees).difference(set(followers)) unfollowers_list = [] for unfollower in unfollowers: unfollowers_list.append( f'{unfollower.full_name} @{unfollower.username}') return '\n'.join(unfollowers_list)
def safe_login(loader: Instaloader, username: str, password: str, session_path: str = './session.pickle'): if os.path.exists(session_path): loader.load_session_from_file(username, session_path) else: loader.login(username, password) loader.save_session_to_file(session_path)
class DownloadProfiles(): """ Realiza download de perfis e posts de usuarios especificados """ def __init__(self, users_list, min_date, sleep, username, password): """ Inicializa objeto """ self._users_list = users_list self._tokenize_date(min_date) self._sleep = sleep self._username = username self._password = password self._out_dir = "data/staging" subprocess.run(["mkdir", "-p", self._out_dir]) self._iloader = Instaloader(download_comments=False, download_pictures=False, download_geotags=False, download_videos=False) self._iloader.login(self._username, self._password) self._iloader.save_session_to_file("./data/session") def _tokenize_date(self, date_str): """ Utilitario que realiza parsing na data dada como parametro """ date_list = date_str.split(",") self._year = int(date_list[0]) self._month = int(date_list[1]) self._day = int(date_list[2]) def download_profiles(self): """ Realiza download de perfis recebidos como entrada """ for user in self._users_list: prof = set() prof.add(Profile.from_username(self._iloader.context, user)) subprocess.run(["mkdir", "-p", str(self._out_dir + "/" + user)]) self._iloader.dirname_pattern = self._out_dir + "/" + str(user) self._iloader.download_profiles( prof, post_filter=lambda post: post.date_utc >= datetime( self._year, self._month, self._day)) time.sleep(self._sleep)
def import_session(cookiefile, sessionfile): print("Using cookies from {}.".format(cookiefile)) conn = connect(cookiefile) try: cookie_data = conn.execute( "SELECT name, value FROM moz_cookies WHERE baseDomain='instagram.com'" ) except OperationalError: cookie_data = conn.execute( "SELECT name, value FROM moz_cookies WHERE host LIKE '%instagram.com'" ) instaloader = Instaloader(max_connection_attempts=1) instaloader.context._session.cookies.update(cookie_data) username = instaloader.test_login() if not username: raise SystemExit("Not logged in. Are you logged in successfully in Firefox?") print("Imported session cookie for {}.".format(username)) instaloader.context.username = username instaloader.save_session_to_file(sessionfile)
def load(username,password): loader = Instaloader() login_name = username target_profile = username # login try: loader.load_session_from_file(login_name) except FileNotFoundError: loader.context.log("Session file does not exist yet - Logging in.") if not loader.context.is_logged_in: loader.login(username, password) loader.save_session_to_file() #if user is new, create them a folder to store their lists if not os.path.exists(f"scrape/user_data/@{login_name}"): os.makedirs(f"scrape/user_data/@{login_name}") profile_pic_url, num_posts, biography = get_user_details(loader.context, target_profile) return profile_pic_url, num_posts, biography
from glob import glob from os.path import expanduser from sqlite3 import connect from instaloader import ConnectionException, Instaloader # FIREFOXCOOKIEFILE = "/home/alex/.mozilla/firefox/l96w6b90.default/cookies.sqlite" FIREFOXCOOKIEFILE = glob( expanduser("~/.mozilla/firefox/*.default/cookies.sqlite"))[0] instaloader = Instaloader(max_connection_attempts=1) instaloader.context._session.cookies.update( connect(FIREFOXCOOKIEFILE).execute("SELECT name, value FROM moz_cookies " "WHERE baseDomain='instagram.com'")) try: username = instaloader.test_login() if not username: raise ConnectionException() except ConnectionException: raise SystemExit( "Cookie import failed. Are you logged in successfully in Firefox?") instaloader.context.username = username instaloader.save_session_to_file()
async def _insta_post_downloader(message: Message): """ download instagram post """ await message.edit('`Setting up Configs. Please don\'t flood.`') dirname = 'instadl_{target}' filename = '{target}\'s_post' insta = Instaloader( dirname_pattern=dirname, filename_pattern=filename, download_video_thumbnails=False, download_geotags=False, download_comments=False, save_metadata=False, compress_json=False ) if Config.INSTA_ID and Config.INSTA_PASS: # try login try: insta.load_session_from_file(Config.INSTA_ID) await message.edit('`Logged in with current Session`') except FileNotFoundError: await message.edit('`Login required. Trying to login`') try: insta.login(Config.INSTA_ID, Config.INSTA_PASS) except InvalidArgumentException: await message.err('Provided `INSTA_ID` is incorrect') return except BadCredentialsException: await message.err('Provided `INSTA_PASS` is incorrect') return except ConnectionException: await message.err('Instagram refused to connect. Try again later or never' ' (your choice)😒') return # This is a nightmare. except TwoFactorAuthRequiredException: # Send a promt for 2FA code in saved messages chat_type = 'Saved Messages' if message.from_user.is_self else 'Private Message' text = ('[<b>2 Factor Authentication Detected</b>]\n' f'I have sent a message to {chat_type}. ' 'Please continue there and send your 2FA code.') await message.edit(text) for _ in range(4): # initial convo with the user who sent message in pm. # if user is_self convo in saved messages # else in pm of sudo user async with xdecha.conversation(message.from_user.id) as asker: asked = await asker.send_message('Please reply me with your 2FA code `int`') response = await asker.get_response(mark_read=True) if not (response.reply_to_message and response.reply_to_message.is_self): # I said reply me. continue code = response.text if not (code.isdigit() and len(code) == 6): # the six digit code # What else it has always been a six digit code. continue try: insta.two_factor_login(code) break except BadCredentialsException as b_c_e: await asked.err(b_c_e) except InvalidArgumentException: await asked.edit('`No pending Login Found`') return else: try: insta.save_session_to_file() except LoginRequiredException: await message.err('Failed to save session file, probably due to invalid login.') await asyncio.sleep(5) else: await message.edit('Login Credentials not found.\n`[NOTE]`: ' '**You may not be able to download private contents or so**') await asyncio.sleep(2) p = r'^https:\/\/www\.instagram\.com\/(p|tv|reel)\/([A-Za-z0-9\-_]*)\/(\?igshid=[a-zA-Z0-9]*)?$' match = re.search(p, message.input_str) if '-u' in message.flags: username = message.filtered_input_str sent = await message.edit(f'`Fetching all posts of {username}`') profile = await get_profile(insta, username) limit = int(message.flags.get("-l", 0)) count = 0 for post in await get_profile_posts(profile): count += 1 if message.process_is_canceled: await sent.edit("Post Download Interrupted...") await asyncio.sleep(5) break try: await download_post(insta, post) await upload_to_tg(message, dirname.format(target=post.owner_username), post) except FloodWait as f_w: await asyncio.sleep(f_w.x + 10) await upload_to_tg(message, dirname.format(target=post.owner_username), post) except (KeyError, LoginRequiredException): await message.err('Private Content Login Required') return finally: shutil.rmtree(dirname.format(target=post.owner_username), ignore_errors=True) if limit > 0 and count == limit: break await sent.delete() elif match: dtypes = { 'p': 'POST', 'tv': 'IGTV', 'reel': 'REELS' } d_t = dtypes.get(match.group(1)) if not d_t: await message.err('Unsupported Format') return sent = await message.edit(f'`Fetching {d_t} Content.`') shortcode = match.group(2) post = await get_post(insta, shortcode) try: await download_post(insta, post) await upload_to_tg(message, dirname.format(target=post.owner_username), post) except (KeyError, LoginRequiredException): await message.err("Post is private. Login and try again") return except FloodWait as f_w: await asyncio.sleep(f_w.x + 5) await upload_to_tg(message, dirname.format(target=post.owner_username), post) finally: shutil.rmtree(dirname.format(target=post.owner_username), ignore_errors=True) await sent.delete() else: await message.err('`Invalid Input`')
async def _insta_post_downloader(event): """ download instagram post """ await event.edit('`Setting up Configs. Please don\'t flood.`') dirname = 'instadl_{target}' filename = '{target}\'s_post' insta = Instaloader(dirname_pattern=dirname, filename_pattern=filename, download_video_thumbnails=False, download_geotags=False, download_comments=False, save_metadata=False, compress_json=False) if Config.INSTA_ID and Config.INSTA_PASS: # try login try: insta.load_session_from_file(Config.INSTA_ID) await event.edit('`Logged in with current Session`') except FileNotFoundError: await event.edit('`Login required. Trying to login`') try: insta.login(Config.INSTA_ID, Config.INSTA_PASS) except InvalidArgumentException: logger.error('Provided `INSTA_ID` is incorrect') return except BadCredentialsException: logger.error('Provided `INSTA_PASS` is incorrect') return except ConnectionException: logger.error( 'Instagram refused to connect. Try again later or never' ' (your choice)😒') return # This is a nightmare. except TwoFactorAuthRequiredException: # Send a promt for 2FA code in saved messages chat_type = 'Saved Messages' text = ('[**2 Factor Authentication Detected**]\n' f'I have sent a message to {chat_type}. ' 'Please continue there and send your 2FA code.') await event.edit(text) for _ in range(4): # initial convo with the user who sent message in pm. # if user is_self convo in saved messages # else in pm of sudo user async with event.client.conversation( event.chat_id) as asker: asked = await asker.send_message( 'Please reply me with your 2FA code `int`') response = await asker.wait_event( events.NewMessage(incoming=True, from_users=event.chat_id)) if not response.text: # I said reply me. continue code = response.text if not (code.isdigit() and len(code) == 6): # the six digit code # What else it has always been a six digit code. continue try: insta.two_factor_login(code) break except BadCredentialsException as b_c_e: await asker.edit(b_c_e) except InvalidArgumentException: await asked.edit('`No pending Login Found`') return else: try: insta.save_session_to_file() except LoginRequiredException: logger.error( 'Failed to save session file, probably due to invalid login.' ) await asyncio.sleep(5) else: await event.edit( 'Login Credentials not found.\n`[NOTE]`: ' '**You may not be able to download private contents or so**') await asyncio.sleep(2) p = r'^(?:https?:\/\/)?(?:www\.)?(?:instagram\.com.*\/(p|tv|reel)\/)([\d\w\-_]+)(?:\/)?(\?.*)?$' match = re.search(p, event.pattern_match.group(1)) if match: dtypes = {'p': 'POST', 'tv': 'IGTV', 'reel': 'REELS'} d_t = dtypes.get(match.group(1)) if not d_t: logger.error('Unsupported Format') return sent = await event.edit(f'`Fetching {d_t} Content.`') shortcode = match.group(2) post = get_post(insta, shortcode) try: download_post(insta, post) await upload_to_tg(event, dirname.format(target=post.owner_username), post) except (KeyError, LoginRequiredException): logger.error("Post is private. Login and try again") return except errors.FloodWaitError: await asyncio.sleep(15) await upload_to_tg(event, dirname.format(target=post.owner_username), post) finally: shutil.rmtree(dirname.format(target=post.owner_username), ignore_errors=True) await sent.delete() else: logger.error('`Invalid Input`')
login_name = auth['login'] target_profile = auth['target_profile'] loader = Instaloader() # login try: loader.load_session_from_file(login_name) except FileNotFoundError: loader.context.log("Session file does not exist yet - Logging in.") if not loader.context.is_logged_in: loader.interactive_login(login_name) loader.save_session_to_file() profile = Profile.from_username(loader.context, target_profile) followers = profile.get_followers() loader.context.log() loader.context.log('Profile {} has {} followers. Writing to file'.format(profile.username, profile.followers)) loader.context.log() followers_file = open('followers.txt', 'a') for follower in followers: followers_file.write(follower.username + '\n') loader.context.log('Finished.')
import os from instaloader import Instaloader, Profile L = Instaloader() bot_username, bot_password = '******', 'xxxx' # Set valid credentials here L.login(bot_username, bot_password) BASE_DIR = os.path.dirname(os.path.abspath(__file__)) session_filename = f'{BASE_DIR}/session-{bot_username}' L.save_session_to_file(session_filename) # L.load_session_from_file(bot_username, filename) def check_follow(username_x, username_y): # Check if username_x is following username_y profile_x = Profile.from_username(L.context, username_x) profile_y = Profile.from_username(L.context, username_y) is_follow = False for followee in profile_x.get_followees(): if followee.userid == profile_y.userid: is_follow = True break return is_follow result = check_follow('yannick_kiki', 'bombe_robii') print(result)
import os try: from instaloader import Instaloader, Profile except ImportError: os.system("pip install instaloader") #replit likes to uninstall things from instaloader import Instaloader import pickle import json L = Instaloader() try: L.load_session_from_file(os.getenv('USERNAME'), 'sess.pkl') except: L.interactive_login(os.getenv('USERNAME')) L.save_session_to_file(filename="sess.pkl") L.close() sess_pickle = open('sess.pkl', 'rb') sess = pickle.load(sess_pickle) f = open("cookies.json", 'w+') json.dump(sess, f) sess_pickle.close() f.close()
async def _insta_post_downloader(message: Message): """ download instagram post """ await message.edit("`Setting up Configs. Please don't flood.`") dirname = "instadl_{target}" filename = "{target}'s_post" insta = Instaloader( dirname_pattern=dirname, filename_pattern=filename, download_video_thumbnails=False, download_geotags=False, download_comments=False, save_metadata=False, compress_json=False, ) if Config.INSTA_ID and Config.INSTA_PASS: # try login try: insta.load_session_from_file(Config.INSTA_ID) await message.edit("`Logged in with current Session`") except FileNotFoundError: await message.edit("`Login required. Trying to login`") try: insta.login(Config.INSTA_ID, Config.INSTA_PASS) except InvalidArgumentException: await message.err("Provided `INSTA_ID` is incorrect") return except BadCredentialsException: await message.err("Provided `INSTA_PASS` is incorrect") return except ConnectionException: await message.err( "Instagram refused to connect. Try again later or never" " (your choice)😒" ) return # This is a nightmare. except TwoFactorAuthRequiredException: # Send a promt for 2FA code in saved messages chat_type = ( "Saved Messages" if message.from_user.is_self else "Private Message" ) text = ( "[<b>2 Factor Authentication Detected</b>]\n" f"I have sent a message to {chat_type}. " "Please continue there and send your 2FA code." ) await message.edit(text) for _ in range(4): # initial convo with the user who sent message in pm. # if user is_self convo in saved messages # else in pm of sudo user async with userge.conversation(message.from_user.id) as asker: asked = await asker.send_message( "Please reply me with your 2FA code `int`" ) response = await asker.get_response(mark_read=True) if not ( response.reply_to_message and response.reply_to_message.is_self ): # I said reply me. continue code = response.text if not (code.isdigit() and len(code) == 6): # the six digit code # What else it has always been a six digit code. continue try: insta.two_factor_login(code) break except BadCredentialsException as b_c_e: await asked.err(b_c_e) except InvalidArgumentException: await asked.edit("`No pending Login Found`") return else: try: insta.save_session_to_file() except LoginRequiredException: await message.err( "Failed to save session file, probably due to invalid login." ) await asyncio.sleep(5) else: await message.edit( "Login Credentials not found. `[NOTE]`: " "**You may not be able to download private contents or so**" ) await asyncio.sleep(2) url_patern = r"^https:\/\/www\.instagram\.com\/(p|tv|reel)\/([A-Za-z0-9\-_]*)\/(\?igshid=[a-zA-Z0-9]*)?$" # pylint: disable=C0301 match = re.search(url_patern, message.input_str) if "-u" in message.flags: username = message.filtered_input_str sent = await message.edit(f"`Fetching all posts of {username}`") profile = await get_profile(insta, username) for post in await get_profile_posts(profile): try: await download_post(insta, post) await upload_to_tg( message, dirname.format(target=post.owner_username), post ) except FloodWait as f_w: await asyncio.sleep(f_w.x + 10) await upload_to_tg( message, dirname.format(target=post.owner_username), post ) except (KeyError, LoginRequiredException): await message.err("Private Content Login Required") return finally: shutil.rmtree( dirname.format(target=post.owner_username), ignore_errors=True ) await sent.delete() elif match: dtypes = {"p": "POST", "tv": "IGTV", "reel": "REELS"} d_t = dtypes.get(match.group(1)) if not d_t: await message.err("Unsupported Format") return sent = await message.edit(f"`Fetching {d_t} Content.`") shortcode = match.group(2) post = await get_post(insta, shortcode) try: await download_post(insta, post) await upload_to_tg( message, dirname.format(target=post.owner_username), post ) except (KeyError, LoginRequiredException): await message.err("Post is private. Login and try again") return except FloodWait as f_w: await asyncio.sleep(f_w.x + 5) await upload_to_tg( message, dirname.format(target=post.owner_username), post ) finally: shutil.rmtree( dirname.format(target=post.owner_username), ignore_errors=True ) await sent.delete() else: await message.err("`Invalid Input`")