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)
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)
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)
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
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
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
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
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 ]
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
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
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
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))
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