예제 #1
0
def press_righ_arrow(pic_number, user, driver):
    if pic_number == 0:
        return UIComponentsAPI().click(
            "pictures_carousel_first_pic_right_arrow", user, driver)
    else:
        return UIComponentsAPI().click(
            "pictures_carousel_not_first_pic_right_arrow", user, driver)
예제 #2
0
def get_followers_following_for_user_one_try(entry,user,driver):
    """
    This function opens the user profile page, and opens the scrollable window of followers or following, according to the 
    entry paramener ("followers" or "following")
    """
    dataAPI().log(user,"get_followers_following_for_user_one_try","INFO","start")
    try:
        profile_url = 'https://www.instagram.com/{}/'.format(user)
        driver.get(profile_url)
    except:
        dataAPI().log(user,"get_followers_following_for_user_one_try","ERROR","couldn't load user profile page")
        return (0,0)
    sleep(1)
    ### Open the followers/ing scrollable window from the profile page + get the # of entries
    if entry == "followers":
        nb_entries = UIComponentsAPI().get_text_and_click("profile_page_followers_button",user,driver)
    else:
        nb_entries = UIComponentsAPI().get_text_and_click("profile_page_following_button",user,driver)
    if nb_entries==0:
        return (0,0)
    sleep(1)
    try:
        nb_entries = treat_number(nb_entries,user)
        #find all elements in list
        fBody_xpath = "//div[@class='isgrP']"    
        fBody = WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.XPATH, fBody_xpath)))
        
        scroll = 0
        while scroll < nb_entries: # each scroll displays ~12 row, we divide by 3 to be reaaaallllyyy sure we don't miss any
            driver.execute_script('arguments[0].scrollTop = arguments[0].scrollTop + arguments[0].offsetHeight;', fBody)
            sleep(1)
            scroll += 1
        
        entries = []
        fails = 0
        sleep(2)
        for n in range(1,nb_entries):
            if fails>3:
                dataAPI().log(user,"get_followers_following_for_user_one_try","ERROR","too many fails to get the entries, stopping execution")
                return (0,0)
            try:
                xpath = "/html/body/div[5]/div/div/div[2]/ul/div/li[{}]".format(n)
                info = WebDriverWait(driver, 2).until(EC.presence_of_element_located((By.XPATH,xpath))).text
                name = info.split("\n")[0]
                entries.append(name)
            except:
                fails+=1
                dataAPI().log(user,"get_followers_following_for_user_one_try","ERROR","couldn't get entry {}".format(n))
                pass

        dataAPI().log(user,"get_followers_following_for_user_one_try","INFO","followers scraped : {0}/{1}".format(len(entries),nb_entries))
        return (entries,nb_entries)
    
    except:
        dataAPI().log(user,"get_followers_following_for_user_one_try","ERROR","UNIDENTIFIED failure, full exception : {}".format(traceback.format_exc())) 
        return (0,0)
예제 #3
0
def follow_from_profile_page(user,driver):
    """
    Once on the profile of a target account, this function tries to follow it.
    Returns 0 if there is an error, or if the account is already followed.
    """
    dataAPI().log(user,"follow_from_profile_page","INFO","start")
    follow_button_text = UIComponentsAPI().get_text("profile_page_follow_button",user,driver)
    if follow_button_text==0:
        return 0
    elif follow_button_text!="Follow":
        dataAPI().log(user,"follow_from_profile_page","INFO","already following this dude, next")
        return 0
    else:
        return UIComponentsAPI().click("profile_page_follow_button",user,driver)
예제 #4
0
def open_browser(user, for_aws=False, headless=False):
    """
    Just opens a browser and Instagram, but doesn't log-in'

    """
    dataAPI().log(user, "open_browser", "INFO", "start function")
    try:
        if for_aws:
            chrome_options = Options()
            chrome_options.add_argument("--disable-extensions")
            chrome_options.add_argument("--disable-dev-shm-usage")
            chrome_options.add_argument('headless')
            chrome_options.add_argument('--no-sandbox')
            driver = webdriver.Chrome(chrome_options=chrome_options)
        else:
            if headless:
                chrome_options = Options()
                chrome_options.add_argument('headless')
                driver = webdriver.Chrome(chrome_options=chrome_options)
            else:
                driver = webdriver.Chrome(
                    executable_path="/usr/local/bin/chromedriver")
        driver.get("https://www.instagram.com/")
        UIComponentsAPI().click("login_accept_cookies", user, driver)
        dataAPI().log(user, "open_browser", "INFO", "success - browser opened")
        return driver
    except:
        dataAPI().log(
            user, "open_browser", "ERROR",
            "failed, full exception : {}".format(traceback.format_exc()))
        smart_sleep(3)
        return 0
예제 #5
0
def get_account_data_from_profile_page(user,driver):
    dataAPI().log(user,"get_account_data_from_profile_page","INFO","start")
    nb_followers = UIComponentsAPI().get_text("profile_page_target_nb_followers",user,driver)
    nb_following = UIComponentsAPI().get_text("profile_page_target_nb_following",user,driver)
    nb_posts = UIComponentsAPI().get_text("profile_page_target_nb_posts",user,driver)    
    account_username = UIComponentsAPI().get_text("profile_page_target_username",user,driver)
    if 0 in  [account_username,nb_posts,nb_followers,nb_following]:
        dataAPI().log(user,"get_account_data_from_profile_page","ERROR","couldn't scrape raw account data properly. What we got : {0}, {1}, {2}, {3}".format(account_username,nb_followers,nb_following,nb_posts))
        return None,None,None,None
    ### Now, if we managed to extract the raw fields, we need to transform them
    try:
        nb_posts = treat_number(nb_posts,user)
        nb_followers = treat_number(nb_followers,user)
        nb_following = treat_number(nb_following,user)
    except:
        dataAPI().log(user,"get_account_data_from_profile_page","ERROR","couldn't properly transform raw account data properly.")
        return None,None,None,None
    dataAPI().log(user,"get_account_data_from_profile_page","INFO","raw account data scraped and transformed successfully : {0}, {1}, {2}, {3}".format(account_username,nb_followers,nb_following,nb_posts))
    return account_username,nb_posts,nb_followers,nb_following
예제 #6
0
def unfollow_account(user_to_unfollow,user,driver):
    dataAPI().log(user,"unfollow_account_from_profile_page","INFO","start, user_to_unfollow={}"+format(user_to_unfollow))
    try:
        driver.get('https://www.instagram.com/{}/'.format(user_to_unfollow))
    except:
        dataAPI().log(user,"unfollow_account_from_profile_page","ERROR","failed to access profile URL")
        return 0
    sleep(1)
    ok = UIComponentsAPI().click("unfollow_button",user,driver)
    if ok==0:
        dataAPI().log(user,"unfollow_account_from_profile_page","ERROR","Failed to unfollow user {}".format(user_to_unfollow))
        return 0
    sleep(2)
    ok = UIComponentsAPI().click("unfollow_red_button_confirm",user,driver)
    if ok==1:
        dataAPI().log(user,"unfollow_account_from_profile_page","INFO","success, account {} unfollowed".format(user_to_unfollow))
        return 1
    else:
        dataAPI().log(user,"unfollow_account_from_profile_page","ERROR","Failed to unfollow user {}".format(user_to_unfollow))
        return 0
예제 #7
0
def log_in(email,password,user,for_aws=True,headless=False):
    dataAPI().log(user,"log_in","INFO","start") 
    try:
        if for_aws:
            chrome_options = Options()
            chrome_options.add_argument("--disable-extensions")
            chrome_options.add_argument("--disable-dev-shm-usage")
            chrome_options.add_argument('headless')
            chrome_options.add_argument('--no-sandbox')
            #chrome_options.add_argument('start-maximized')
            driver = webdriver.Chrome(chrome_options=chrome_options)
        else:
            if headless:
                chrome_options = Options()
                chrome_options.add_argument('headless')
                driver = webdriver.Chrome(chrome_options=chrome_options)
            else:
                driver = webdriver.Chrome()
        
        driver.get('https://www.instagram.com/accounts/login/?source=auth_switcher')
        
        UIComponentsAPI().click("login_accept_cookies",user,driver)
        step1 = UIComponentsAPI().enter_text("login_email_input_field",email,user,driver)
        step2 = UIComponentsAPI().enter_text("login_password_input_field",password,user,driver) 
        step3 = UIComponentsAPI().click("login_connexion_button",user,driver)
        
        if step1+step2+step3<3:
            dataAPI().log(user,"log_in","ERROR","failed") 
            return 0
        else:
            dataAPI().log(user,"log_in","INFO","success")  
            sleep(3)
            return driver
    except:
        dataAPI().log(user,"log_in","ERROR","failed, full exception : {}".format(traceback.format_exc()))  
        sleep(3)
        return 0
예제 #8
0
def get_account_data_from_profile_page(user, driver):
    dataAPI().log(user, "get_account_data_from_profile_page", "INFO",
                  "start function")
    username = UIComponentsAPI().get_text("profile_page_target_username", user,
                                          driver)
    name = UIComponentsAPI().get_text("profile_page_target_name", user, driver)
    nb_followers = UIComponentsAPI().get_text(
        "profile_page_target_nb_followers", user, driver)
    nb_following = UIComponentsAPI().get_text(
        "profile_page_target_nb_following", user, driver)
    nb_posts = UIComponentsAPI().get_text("profile_page_target_nb_posts", user,
                                          driver)
    description = UIComponentsAPI().get_text("profile_page_target_description",
                                             user,
                                             driver,
                                             is_warning=True)
    nb_likes_per_post = 0  ## incoming
    if description == 0:
        description = ""
    ### Everything is required except the description
    if 0 in [username, name, nb_posts, nb_followers, nb_following]:
        dataAPI().log(
            user, "get_account_data_from_profile_page", "ERROR",
            "couldn't scrape raw account data properly for user {0}. What we got : {1}, {2}, {3}, {4}, {5}"
            .format(user, username, name, nb_followers, nb_following,
                    nb_posts))
        return []
    ### Now, if we managed to extract the raw fields, we need to transform them
    try:
        nb_posts = treat_number(nb_posts, user)
        nb_followers = treat_number(nb_followers, user)
        nb_following = treat_number(nb_following, user)
    except:
        dataAPI().log(
            user, "get_account_data_from_profile_page", "ERROR",
            "couldn't properly transform raw account data for user {}".format(
                user))
        return []
    dataAPI().log(
        user, "get_account_data_from_profile_page", "INFO",
        "raw account data scraped and transformed successfully : {0}, {1}, {2}, {3}, {4}"
        .format(username, name, nb_followers, nb_following, nb_posts))
    return [
        username, name, nb_followers, nb_following, nb_posts, description,
        nb_likes_per_post
    ]
예제 #9
0
def unfollow_one_account(user_to_unfollow, user, driver):
    dataAPI().log(user, "unfollow_one_account", "INFO", "start function")
    dataAPI().log(user, "unfollow_one_account", "INFO",
                  "start, user_to_unfollow={}".format(user_to_unfollow))
    ### Sometimes the unfollow fails even if the right buttons are clicked according to stupid Selenium...
    # So we have to check if the account is effectively unfollowed. If not re retry in the limit of 2 fails.
    fails = 0
    while fails <= 2:
        dataAPI().log(user, "unfollow_one_account", "INFO",
                      "trying to unfollow.. {} tries so far".format(fails))
        try:
            driver.get(
                'https://www.instagram.com/{}/'.format(user_to_unfollow))
        except:
            dataAPI().log(
                user, "unfollow_one_account", "WARNING",
                "failed to access profile URL of user".format(
                    "user_to_unfollow"))
            fails += 1
            continue

        status = UIComponentsAPI().get_text(
            "profile_page_follow_status_button", user, driver)
        print("Status is {}".format(status))
        if status == "Follow":
            dataAPI().log(user, "unfollow_one_account", "INFO",
                          "this account is not followed... stop")
            return 0

        smart_sleep(2)
        ok = UIComponentsAPI().click("unfollow_button", user, driver)
        if ok == 0:
            dataAPI().log(
                user, "unfollow_one_account", "WARNING",
                "Failed to unfollow user {} - 1st unfollow click".format(
                    user_to_unfollow))
            fails += 1
            continue
        smart_sleep(2)
        if UIComponentsAPI().click("unfollow_red_button_confirm", user,
                                   driver):
            smart_sleep(4)
            driver.get(
                'https://www.instagram.com/{}/'.format(user_to_unfollow))
            ### In theory the unfollow has been confirmed, but we need to double check...
            status = UIComponentsAPI().get_text(
                "profile_page_follow_status_button", user, driver)
            print("Status is {}".format(status))
            if status == "Follow":  ### Which means we are not following the guy anymore :)
                dataAPI().log(
                    user, "unfollow_one_account", "INFO",
                    "success, account {} unfollowed".format(user_to_unfollow))
                return 1
            else:
                dataAPI().log(
                    user, "unfollow_one_account", "WARNING",
                    "{} still not unfollowed, we try again...".format(
                        user_to_unfollow))
                fails += 1
                continue
        else:
            dataAPI().log(
                user, "unfollow_one_account", "WARNING",
                "Failed to unfollow user {} - 2nd unfollow click".format(
                    user_to_unfollow))
            fails += 1
            continue

    dataAPI().log(
        user, "unfollow_one_account", "ERROR",
        "(probably) failed to unfollow user {}...".format(user_to_unfollow))
    return 0
예제 #10
0
def log_in(email,
           password,
           user,
           use_cookies=True,
           headless=False,
           for_aws=False):
    """
    This function creates a webdriver, and log-in into Instagram for the specified user.
    It returns the webdriver for performing further actions.

    """
    dataAPI().log(user, "log_in", "INFO", "start function")
    try:
        if for_aws:
            chrome_options = Options()
            chrome_options.add_argument("--disable-extensions")
            chrome_options.add_argument("--disable-dev-shm-usage")
            chrome_options.add_argument('headless')
            chrome_options.add_argument('--no-sandbox')
            driver = webdriver.Chrome(chrome_options=chrome_options)
        else:
            if headless:
                chrome_options = Options()
                chrome_options.add_argument('headless')
                ### By default, the window size of headless chrome is 800x600, we want a bigger one
                chrome_options.add_argument('--window-size=1200,753')
                ### Instagram detects headles browsers (fyi not all websites care about wether the visitor is headless or not, but insta does)
                ### So we pretend we are a normal browser (therefore we pass the headless browser test : https://stackoverflow.com/questions/55364643/headless-browser-detection)
                chrome_options.add_argument(
                    "user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
                )
                driver = webdriver.Chrome(chrome_options=chrome_options)
            else:
                driver = webdriver.Chrome()

        driver.get(
            'https://www.instagram.com/accounts/login/?source=auth_switcher')
        smart_sleep(2)
        dataAPI().log(user, "log_in", "INFO",
                      "authentication page successfully loaded")
        UIComponentsAPI().click("login_accept_cookies", user, driver)

        ################## Cookies_management ####################################
        pwd_hash = sum([ord(c) for c in password])
        cookies_file_path = "cookies/cookies_" + email.split(
            "@")[0] + "_" + str(pwd_hash) + ".pkl"
        if use_cookies:
            ### We check if there are loadable coolies for that email+password
            try:
                load_cookie(driver, cookies_file_path)
                cookies_loaded = True
                dataAPI().log(user, "log_in", "INFO",
                              "cookies loaded for email : {}".format(email))
            except:
                dataAPI().log(
                    user, "log_in", "INFO",
                    "cookies NOT loaded for email : {}".format(email))
                cookies_loaded = False
                pass
            smart_sleep(2)
            ### If cookies are loaded for that email+pwd, we refresh
            # Normally that is sufficient log-in
            # We check that the log-in was successful, and if yes we update the cookies
            if cookies_loaded:
                driver.refresh()
                smart_sleep(3)
                ### login-check (just to check that the log-in was successful)
                login_ok = UIComponentsAPI().get("homepage_searchbar", user,
                                                 driver)
                if login_ok != 0:
                    ### Finally we (try to) click on all the pop-ups to look human
                    UIComponentsAPI().click("homepage_save_login_infos",
                                            user,
                                            driver,
                                            is_warning=True)
                    smart_sleep(4)
                    UIComponentsAPI().click("homepage_notifications_notnow",
                                            user,
                                            driver,
                                            is_warning=True)
                    smart_sleep(1)
                    save_cookie(driver, cookies_file_path
                                )  #update (=overwriting) of the cookies
                    dataAPI().log(
                        user, "log_in", "INFO",
                        "success using cookies, and cookies refreshed")
                    return driver
                else:
                    dataAPI().log(
                        user, "log_in", "WARNING",
                        "cookies file loaded, but apparently the log-in didn't work... So we enter the email+password"
                    )

            ### If no cookies found for that email, or if the login-check failed, we log-in and then store the cookies
            step1 = UIComponentsAPI().enter_text("login_email_input_field",
                                                 email, user, driver)
            step2 = UIComponentsAPI().enter_text("login_password_input_field",
                                                 password, user, driver)
            step3 = UIComponentsAPI().click("login_connexion_button", user,
                                            driver)
            if step1 + step2 + step3 < 3:
                dataAPI().log(user, "log_in", "ERROR", "failed")
                return 0
            else:
                smart_sleep(3)
                ### Finally we (try to) click on all the pop-ups to look human
                try:
                    smart_sleep(1)
                    UIComponentsAPI().click("homepage_save_login_infos",
                                            user,
                                            driver,
                                            is_warning=True)
                    smart_sleep(4)
                    UIComponentsAPI().click("homepage_notifications_notnow",
                                            user,
                                            driver,
                                            is_warning=True)
                    smart_sleep(1)
                except:
                    pass
                save_cookie(driver, cookies_file_path)
                dataAPI().log(user, "log_in", "INFO",
                              "success, and cookies saved")
                return driver
        ########################################################################

        ### If cookies use is forbidden
        step1 = UIComponentsAPI().enter_text("login_email_input_field", email,
                                             user, driver)
        step2 = UIComponentsAPI().enter_text("login_password_input_field",
                                             password, user, driver)
        step3 = UIComponentsAPI().click("login_connexion_button", user, driver)

        if step1 + step2 + step3 < 3:
            dataAPI().log(user, "log_in", "ERROR", "failed")
            return 0
        else:
            dataAPI().log(user, "log_in", "INFO", "success")
            smart_sleep(3)
            ### Finally we don't want the notifications (if asked)
            try:
                smart_sleep(1)
                UIComponentsAPI().click("homepage_notifications_notnow", user,
                                        driver)
            except:
                pass
            return driver
    except:
        dataAPI().log(
            user, "log_in", "ERROR",
            "failed, full exception : {}".format(traceback.format_exc()))
        smart_sleep(3)
        return 0
예제 #11
0
def follow_accounts_from_hashtag(hashtag, nb_follows, user, driver):
    dataAPI().log(user, "follow_accounts_from_hashtag", "INFO",
                  "start function")
    dataAPI().log(user, "follow_accounts_from_hashtag", "INFO",
                  "start, #{}".format(hashtag))

    driver.get('https://www.instagram.com/explore/tags/' + hashtag + '/')
    smart_sleep(2)
    ok = UIComponentsAPI().click("first_thumbnail_photo", user, driver)
    if ok == 0:
        dataAPI().log(
            user, "follow_accounts_from_hashtag", "ERROR",
            "fail, full exception : {}".format(traceback.format_exc()))
        smart_sleep(3)
        return 0

    pic_number = 0
    nb_accounts_followed = 0
    failures = 0
    while nb_accounts_followed < nb_follows:

        ### In each iteration : 3 main steps that can fail :
        # - step 1 : getting the account name
        # - step 2 : getting the account details (number of posts, followers,...)
        # - step 3 : follow the account
        # Whenever 1 of these fail, we try to move to the next picture (press_right_arrow)
        # If the press fails, we are doomed : we just stop the loop (break), and therefore the whole function
        # If the press succeeds, we go to the next iteration (continue), and we log 1 fail (failures+=1)
        # After 4 fails, we just give up and end the loop.
        if failures >= 6:
            dataAPI().log(user, "follow_accounts_from_hashtag", "ERROR",
                          "Too many failures, we stop the function")
            return 0

        ### Step 1
        account_username = UIComponentsAPI().get_text(
            "picture_carousel_account_name", user, driver)
        if account_username == 0:
            right_arrow_pressed = press_righ_arrow(pic_number, user, driver)
            if right_arrow_pressed == 0:
                dataAPI().log(user, "follow_accounts_from_hashtag", "ERROR",
                              "stop the function, right arrow press failed")
                return 0
            failures += 1
            continue
        dataAPI().log(
            user, "follow_accounts_from_hashtag", "INFO",
            "start processing for account : {}".format(account_username))

        ### Step 2
        account_url = "https://www.instagram.com/" + account_username + "/"
        driver.execute_script("window.open('');")
        driver.switch_to.window(driver.window_handles[1])
        driver.get(account_url)
        account_info = get_account_data_from_profile_page(user, driver)
        if len(account_info) == 0:
            driver.close()
            driver.switch_to.window(driver.window_handles[0])
            right_arrow_pressed = press_righ_arrow(pic_number, user, driver)
            if right_arrow_pressed == 0:
                dataAPI().log(user, "follow_accounts_from_hashtag", "ERROR",
                              "stop the function, right arrow press failed")
                return 0
            failures += 1
            continue

        ### Step 3
        follow_success = follow_one_account_from_profile_page(
            account_username, user, driver)
        if follow_success == 0:
            driver.close()
            driver.switch_to.window(driver.window_handles[0])
            right_arrow_pressed = press_righ_arrow(pic_number, user, driver)
            if right_arrow_pressed == 0:
                dataAPI().log(user, "follow_accounts_from_hashtag", "ERROR",
                              "stop the function, right arrow press failed")
                return 0
            pic_number += 1
            failures += 1
            smart_sleep(2)
            continue
        dataAPI().log(
            user, "follow_accounts_from_hashtag", "INFO",
            "successfully followed account : {}".format(account_username))

        ### The 3 steps succeeded, lets' move to the less important bits
        driver.close()
        driver.switch_to.window(driver.window_handles[0])

        first_pic_liked = 0
        if np.random.randint(2):
            first_pic_liked = UIComponentsAPI().click(
                "pictures_carousel_like_button", user, driver)

        ### IMPORTANT VARIABLE : number of hours max before unfollowing !
        ### The bot follows each accounts for a random limited amount of hours - between 2 and 24 hours.
        record = {
            "follow_time": datetime.datetime.now(),
            "account_username": account_info[0],
            "account_name": account_info[1],
            "account_nb_followers": account_info[2],
            "account_nb_following": account_info[3],
            "account_nb_posts": account_info[4],
            "account_description": account_info[5],
            "account_nb_likes_per_post": account_info[6],
            "account_source": "follow_accounts_from_hashtag",
            "account_source_attributes": {
                "hashtag": hashtag
            },
            "first_pic_liked": first_pic_liked,
            "hours_before_unfollowing": np.random.randint(2, 24, 1)[0],
            "unfollow_time": None
        }
        dataAPI().add_record("follow_actions", user, record)
        nb_accounts_followed += 1
        smart_sleep(10)

        success_right_arrow_press = press_righ_arrow(pic_number, user, driver)
        if success_right_arrow_press == 0:
            dataAPI().log(user, "follow_accounts_from_hashtag", "ERROR",
                          "stop the function, right arrow press failed")
            return 0
        pic_number = 1

    dataAPI().log(
        user, "follow_accounts_from_hashtag", "INFO",
        "hashtag {0} processed, {1} accounts followed".format(
            hashtag, nb_accounts_followed))
    smart_sleep(3)
    return 1
예제 #12
0
def follow_first_followers(account_username, nb_follows, user, driver):
    dataAPI().log(user, "follow_first_followers", "INFO", "start function")
    dataAPI().log(user, "follow_first_followers", "INFO",
                  "start for account {}".format(account_username))

    ### 1 - access account page
    account_url = "https://www.instagram.com/" + account_username + "/"
    try:
        driver.get(account_url)
    except:
        dataAPI().log(user, "follow_first_followers", "ERROR",
                      "couldn't access account page")
        return 0
    smart_sleep(2)

    ### 2 - open the list of followers of the account
    try:
        nb_followers = UIComponentsAPI().get_text_and_click(
            "profile_page_followers_button", user, driver)
        nb_followers = treat_number(nb_followers, user)
    except:
        dataAPI().log(user, "follow_first_followers", "ERROR",
                      "couldn't access followers list")
        return 0
    smart_sleep(5)

    ### 3 - follow some of the account's followers
    nb_follows = min(nb_follows, nb_followers)
    dataAPI().log(
        user, "follow_first_followers", "INFO",
        "Let's follow {} of the account's followers".format(nb_follows))
    nb_accounts_followed = 0
    fails = 0
    n = 2
    while (nb_accounts_followed < nb_follows) and (fails < 3):
        try:
            xpath = "/html/body/div[5]/div/div/div[2]/ul/div/li[{}]/div/div[2]/div[1]/div/div/span/a".format(
                n)
            target_username = WebDriverWait(driver, 2).until(
                EC.presence_of_element_located(
                    (By.XPATH, xpath))).text.split("\n")[0]
        except:
            dataAPI().log(
                user, "follow_first_followers", "WARNING",
                "couldn't get username for follower account number {}".format(
                    n))
            fails += 1
            n += 1
            smart_sleep(3)
            continue
        driver.execute_script("window.open('');")
        driver.switch_to.window(driver.window_handles[1])
        smart_sleep(2)
        account_info = get_account_data_and_follow(target_username, user,
                                                   driver)
        smart_sleep(2)
        driver.close()
        driver.switch_to.window(driver.window_handles[0])
        smart_sleep(2)

        if len(account_info) == 0:
            dataAPI().log(
                user, "follow_first_followers", "WARNING",
                "couldn't follow + get data for follower account number {}".
                format(n))
            fails += 1
            n += 1
            continue

        ### We log the follow
        record = {
            "follow_time": datetime.datetime.now(),
            "account_username": account_info[0],
            "account_name": account_info[1],
            "account_nb_followers": account_info[2],
            "account_nb_following": account_info[3],
            "account_nb_posts": account_info[4],
            "account_description": account_info[5],
            "account_nb_likes_per_post": account_info[6],
            "account_source": "follow_first_followers",
            "account_source_attributes": {
                "account": account_username
            },
            "first_pic_liked": 0,
            "hours_before_unfollowing": np.random.randint(2, 24, 1)[0],
            "unfollow_time": None
        }
        dataAPI().add_record("follow_actions", user, record)
        nb_accounts_followed += 1
        n += 1
        dataAPI().log(
            user, "follow_first_followers", "INFO",
            "successfully followed account {}".format(target_username))
        smart_sleep(10)
    dataAPI().log(user, "follow_first_followers", "INFO",
                  "end - follow_first_followers".format(nb_accounts_followed))
예제 #13
0
def explore_hashtag(hashtag,nb_follows,user,driver):
    dataAPI().log(user,"explore_hashtag","INFO","start, #{}".format(hashtag))  
    
    driver.get('https://www.instagram.com/explore/tags/'+ hashtag + '/')
    sleep(2)
    ok = UIComponentsAPI().click("first_thumbnail_photo",user,driver)
    if ok==0:
        dataAPI().log(user,"explore_hashtag","ERROR","fail, full exception : {}".format(traceback.format_exc()))  
        sleep(3)
        return 0
        
    pic_number = 0
    nb_accounts_followed = 0
    while nb_accounts_followed < nb_follows:
        
        account_username = UIComponentsAPI().get_text("picture_carousel_account_name",user,driver)
        if account_username==0:
            right_arrow_pressed = press_righ_arrow(pic_number,user,driver)
            if right_arrow_pressed == 0:
                dataAPI().log(user,"explore_hashtag","ERROR","stop the processing of hashtag {}".format(hashtag))
                break
            continue
        
        dataAPI().log(user,"explore_hashtag","INFO","start processing for account : {}".format(account_username))
        
        account_url = "https://www.instagram.com/"+account_username+"/"
        driver.execute_script("window.open('');")
        driver.switch_to.window(driver.window_handles[1])
        driver.get(account_url)        
        account_username,nb_posts,nb_followers,nb_followed = get_account_data_from_profile_page(user,driver)   

        if None in [account_username,nb_posts,nb_followers,nb_followed]:
            driver.close()
            driver.switch_to.window(driver.window_handles[0])
            right_arrow_pressed = press_righ_arrow(pic_number,user,driver)
            if right_arrow_pressed == 0:
                dataAPI().log(user,"explore_hashtag","ERROR","stop the processing of hashtag {}".format(hashtag))
                break
            continue
        
        follow_success = follow_from_profile_page(user,driver)  
        if follow_success==0:
            driver.close()
            driver.switch_to.window(driver.window_handles[0])
            right_arrow_pressed = press_righ_arrow(pic_number,user,driver)
            if right_arrow_pressed == 0:
                dataAPI().log(user,"explore_hashtag","ERROR","stop the processing of hashtag {}".format(hashtag))
                break
            pic_number+=1
            continue
        dataAPI().log(user,"explore_hashtag","INFO","successfully followed account : {}".format(account_username))

        driver.close()
        driver.switch_to.window(driver.window_handles[0])
         
        first_pic_liked = 0
        if np.random.randint(2):
            first_pic_liked = UIComponentsAPI().click("pictures_carousel_like_button",user,driver)
                                           
        record = {"follow_time" : datetime.datetime.now(),
                  "account_username" : account_username,
                  "account_nb_followers" : nb_followers,
                  "account_nb_posts" : nb_posts,
                  "hashtag" : hashtag, 
                  "first_pic_liked" : first_pic_liked,
                  "days_before_unfollowing" : np.random.randint(1,5,1)[0],
                  "unfollow_time" : None}
        dataAPI().add_record("follow_actions",user,record)
               
        success_right_arrow_press = press_righ_arrow(pic_number,user,driver)
        if success_right_arrow_press==0:
            dataAPI().log(user,"explore_hashtag","ERROR","stop the processing of hashtag {}".format(hashtag))
            break
        pic_number=1
        nb_accounts_followed+=1
    
    dataAPI().log(user,"explore_hashtag","INFO","hashtag {0} processed, {1} accounts followed".format(hashtag,nb_accounts_followed))
    sleep(3)
    return 1