示例#1
0
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)
示例#2
0
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)
示例#3
0
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)
示例#4
0
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)
示例#6
0
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
示例#7
0
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()
示例#8
0
文件: instadl.py 项目: ayay182/xdecha
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`')
示例#9
0
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`')
示例#10
0
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.')
示例#11
0
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)
示例#12
0
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()
示例#13
0
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`")