def count_new_followers(self, sleep_delay=2): web_address_navigator(Settings, self.browser, "https://medium.com/notifications") self.logger.info('Browsing my notifications') delay_random = random.randint(ceil(sleep_delay * 0.85), ceil(sleep_delay * 1.14)) sleep(delay_random) rows = self.browser.find_elements_by_css_selector( "div > div > div > main > div > div > div > div > div > div > div > div > div > section > div > div > div > div > div > article > div > div" ) cnt = 0 for row in rows: try: if "followed you" in row.text: # self.logger.info(row.text) if "others" in row.text: splitted = row.text.split('others')[0].split(' ') splitted = [x for x in splitted if x] cnt = cnt + int(splitted[-1]) + 1 elif "others" in row.text: cnt = cnt + 2 else: cnt = cnt + 1 except Exception as e: self.logger.error(e) return cnt
def verify_action(browser, action, track, username, person, person_id, logger, logfolder): """ Verify if the action has succeeded """ # currently supported actions are follow & unfollow if action in ["follow", "unfollow"]: if action == "follow": post_action_text = "//button[text()='Following' or text(" ")='Requested']" elif action == "unfollow": post_action_text = "//button[text()='Follow' or text()='Follow " "Back']" button_change = explicit_wait(browser, "VOEL", [post_action_text, "XPath"], logger, 7, False) if not button_change: reload_webpage(browser, Settings) following_status, follow_button = get_following_status( browser, track, username, person, person_id, logger, logfolder) # find action state *.^ if following_status in ["Following", "Requested"]: action_state = False if action == "unfollow" else True elif following_status in ["Follow", "Follow Back"]: action_state = True if action == "unfollow" else False else: action_state = None # handle it! if action_state is True: logger.info( "Last {} is verified after reloading the page!".format( action)) elif action_state is False: # try to do the action one more time! click_visibly(browser, Settings, follow_button) if action == "unfollow": sleep(4) # TODO: use explicit wait here confirm_unfollow(browser) button_change = explicit_wait(browser, "VOEL", [post_action_text, "XPath"], logger, 9, False) if not button_change: logger.warning("Phew! Last {0} is not verified." "\t~'{1}' might be temporarily blocked " "from {0}ing\n".format(action, username)) sleep(210) return False, "temporary block" elif action_state is None: logger.error( "Hey! Last {} is not verified out of an unexpected " "failure!".format(action)) return False, "unexpected" return True, "success"
def search_and_apply(self): usualjobslink = "https://www.linkedin.com/jobs" web_address_navigator(Settings, self.browser, usualjobslink) job_title_XP = '//input[contains(@id,"jobs-search-box-keyword-id")]' txt_job_title = self.browser.find_element_by_xpath(job_title_XP) print('Entering Job Title') (ActionChains(self.browser).move_to_element( txt_job_title).click().send_keys("Python Developer").perform()) job_location_XP = '//input[contains(@id,"jobs-search-box-location-id")]' txt_job_location = self.browser.find_element_by_xpath(job_location_XP) print('Entering Job Location') (ActionChains( self.browser).move_to_element(txt_job_location).click().send_keys( "San Jose, California, United States").perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) print("Clicking Search Button") job_search_XP = '//button[contains(@class,"jobs-search-box__submit-button")]' btn_job_search = self.browser.find_element_by_xpath(job_search_XP) print(btn_job_search) (ActionChains( self.browser).move_to_element(btn_job_search).click().perform()) # update server calls update_activity(Settings) sleep(10) input("Press Enter to continue...")
def post_unfollow_cleanup(state, username, person, relationship_data, person_id, logger, logfolder): """ Casual local data cleaning after an unfollow """ if not isinstance(state, list): state = [state] delete_line_from_file( "{0}{1}_followedPool.csv".format(logfolder, username), person, logger) if "successful" in state: if person in relationship_data[username]["all_following"]: relationship_data[username]["all_following"].remove(person) if "uncertain" in state: # this user was found in our unfollow list but currently is not # being followed logtime = get_log_time() log_uncertain_unfollowed_pool(username, person, logger, logfolder, logtime, person_id) # take a generic 3 seconds of sleep per each uncertain unfollow sleep(3) # save any unfollowed person log_record_all_unfollowed(username, person, logger, logfolder) print('')
def unfriend_user(browser, track, login, userid_to_unfriend, button, blacklist, logger, logfolder, sleep_delay): """ UnFriend a user either from the profile page or post page or dialog box """ user_link = "https://www.facebook.com/{}/".format(userid_to_unfriend) web_address_navigator(browser, user_link, logger, Settings) delay_random = random.randint(ceil(sleep_delay * 0.85), ceil(sleep_delay * 1.14)) try: friend_button_elem = browser.find_element_by_css_selector( "div#pagelet_timeline_profile_actions > div.FriendButton > a > span > span" ) ActionChains(browser).move_to_element(friend_button_elem).perform() ActionChains(browser).click().perform() sleep(delay_random) unfriend_button = browser.find_element_by_xpath( "//*[contains(text(), 'Unfriend')]") unfriend_button.click() logger.info("---> {} has been successfully unfriended".format( userid_to_unfriend)) sleep(delay_random) return True, "success" except Exception as e: logger.error("Failed to unfriend {}, with error {}".format( userid_to_unfriend, e)) return False, ""
def comment_image(browser, username, comments, blacklist, logger, logfolder, Settings): """Checks if it should comment on the image""" # check action availability if quota_supervisor(Settings, "comments") == "jump": return False, "jumped" rand_comment = random.choice(comments).format(username) rand_comment = emoji.demojize(rand_comment) rand_comment = emoji.emojize(rand_comment, use_aliases=True) open_comment_section(browser, logger) comment_input = get_comment_input(browser) try: if len(comment_input) > 0: comment_input[0].clear() comment_input = get_comment_input(browser) # below, an extra space is added to force # the input box to update the reactJS core comment_to_be_sent = rand_comment + " " browser.execute_script( "arguments[0].value = arguments[1];", comment_input[0], comment_to_be_sent, ) # below, it also will remove that extra space added above # COS '\b' is a backspace char in ASCII comment_input[0].send_keys("\b") comment_input = get_comment_input(browser) comment_input[0].submit() update_activity(Settings, "comments") if blacklist["enabled"] is True: action = "commented" add_user_to_blacklist( username, blacklist["campaign"], action, logger, logfolder ) else: logger.warning( "--> Comment Action Likely Failed!" "\t~comment Element was not found" ) return False, "commenting disabled" except InvalidElementStateException: logger.warning( "--> Comment Action Likely Failed!" "\t~encountered `InvalidElementStateException` :/" ) return False, "invalid element state" logger.info("--> Commented: {}".format(rand_comment.encode("utf-8"))) # get the post-comment delay time to sleep naply = get_action_delay("comment", Settings) sleep(naply) return True, "success"
def get_links(browser, page, logger, media, element): # Get image links in scope from hashtag, location and other pages link_elems = element.find_elements_by_tag_name('a') sleep(2) links = [] try: if link_elems: new_links = [link_elem.get_attribute('href') for link_elem in link_elems if link_elem and link_elem.text in media] links.extend(new_links) else: logger.info("'{}' page does not contain a picture".format(page)) except BaseException as e: logger.error("link_elems error {}".format(str(e))) return links
def endorse(self, profile_link, sleep_delay): try: web_address_navigator(Settings, self.browser, profile_link) for jc in range(1, 10): sleep(1) self.browser.execute_script( "window.scrollTo(0, document.body.scrollHeight*" + str(jc) + "/10);") skills_pane = self.browser.find_element_by_css_selector( "div.profile-detail > div.pv-deferred-area > div > section.pv-profile-section.pv-skill-categories-section" ) if (skills_pane.text.split('\n')[0] == 'Skills & Endorsements'): try: first_skill_button_icon = self.browser.find_element_by_css_selector( "div.profile-detail > div.pv-deferred-area > div > section.pv-profile-section.pv-skill-categories-section > ol > li > div > div > div > button > li-icon" ) button_type = first_skill_button_icon.get_attribute("type") if button_type == 'plus-icon': first_skill_button = self.browser.find_element_by_css_selector( "div.profile-detail > div.pv-deferred-area > div > section.pv-profile-section.pv-skill-categories-section > ol > li > div > div > div > button" ) self.browser.execute_script( "var evt = document.createEvent('MouseEvents');" + "evt.initMouseEvent('click',true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0,null);" + "arguments[0].dispatchEvent(evt);", first_skill_button) first_skill_title = self.browser.find_element_by_css_selector( "div.profile-detail > div.pv-deferred-area > div > section.pv-profile-section.pv-skill-categories-section > ol > li > div > div > p > a > span" ) print(first_skill_title.text, "clicked") delay_random = random.randint(ceil(sleep_delay * 0.85), ceil(sleep_delay * 1.14)) sleep(delay_random) else: self.logger.info( 'button_type already {}'.format(button_type)) except Exception as e: self.logger.error(e) else: self.logger.info('Skill & Endorsements pane not found') except Exception as e: self.logger.error(e)
def unfriend_user_by_url(browser, track, login, url, button, blacklist, logger, logfolder, sleep_delay): """ UnFriend a user either from the profile page or post page or dialog box """ web_address_navigator( browser, url, Settings) delay_random = random.randint( ceil(sleep_delay * 0.85), ceil(sleep_delay * 1.14)) try: friend_button_elem = browser.find_element_by_css_selector("div#pagelet_timeline_profile_actions > div.FriendButton > a > span > span") ActionChains(browser).move_to_element(friend_button_elem).perform() ActionChains(browser).click().perform() sleep(delay_random*2) unfriend_button = browser.find_element_by_xpath("//*[contains(text(), 'Unfriend')]") unfriend_button.click() sleep(delay_random) return True, "success" except Exception as e: logger.error(e) return False, ""
def web_address_navigator(Settings, browser, link): """Checks and compares current URL of web page and the URL to be navigated and if it is different, it does navigate""" current_url = get_current_url(browser) total_timeouts = 0 page_type = None # file or directory # remove slashes at the end to compare efficiently if current_url is not None and current_url.endswith('/'): current_url = current_url[:-1] if link.endswith('/'): link = link[:-1] page_type = "dir" # slash at the end is a directory new_navigation = (current_url != link) if current_url is None or new_navigation: link = link + '/' if page_type == "dir" else link # directory links # navigate faster while True: try: browser.get(link) # update server calls update_activity(Settings) sleep(2) break except TimeoutException as exc: if total_timeouts >= 7: raise TimeoutException( "Retried {} times to GET '{}' webpage " "but failed out of a timeout!\n\t{}".format( total_timeouts, str(link).encode("utf-8"), str(exc).encode("utf-8"))) total_timeouts += 1 sleep(2)
def confirm_unfollow(browser): """ Deal with the confirmation dialog boxes during an unfollow """ attempt = 0 while attempt < 3: try: attempt += 1 button_xp = "//button[text()='Unfollow']" # "//button[contains( # text(), 'Unfollow')]" unfollow_button = browser.find_element_by_xpath(button_xp) if unfollow_button.is_displayed(): click_element(browser, Settings, unfollow_button) sleep(2) break except (ElementNotVisibleException, NoSuchElementException) as exc: # prob confirm dialog didn't pop up if isinstance(exc, ElementNotVisibleException): break elif isinstance(exc, NoSuchElementException): sleep(1)
def like_image(browser, username, blacklist, logger, logfolder, Settings): """Likes the browser opened image""" # check action availability if quota_supervisor(Settings, "likes") == "jump": return False, "jumped" like_xpath = "//section/span/button/span[@aria-label='Like']" unlike_xpath = "//section/span/button/span[@aria-label='Unlike']" # find first for like element like_elem = browser.find_elements_by_xpath(like_xpath) if len(like_elem) == 1: # sleep real quick right before clicking the element sleep(2) click_element(browser, Settings, like_elem[0]) # check now we have unlike instead of like liked_elem = browser.find_elements_by_xpath(unlike_xpath) if len(liked_elem) == 1: logger.info('--> Image Liked!') update_activity(Settings, 'likes') if blacklist['enabled'] is True: action = 'liked' add_user_to_blacklist(username, blacklist['campaign'], action, logger, logfolder) # get the post-like delay time to sleep naply = get_action_delay("like", Settings) sleep(naply) return True, "success" else: # if like not seceded wait for 2 min logger.info('--> Image was not able to get Liked! maybe blocked ?') sleep(120) else: liked_elem = browser.find_elements_by_xpath(unlike_xpath) if len(liked_elem) == 1: logger.info('--> Image already liked!') return False, "already liked" logger.info('--> Invalid Like Element!') return False, "invalid element"
def search_and_apply(self, job_title, job_location, distance=50, random_start=True, max_pages=20, max_connects=25, sleep_delay=6): self.logger.info( "Searching for: job_title={}, job_location={}, radius={}".format( job_title, job_location, distance)) connects = 0 prev_connects = -1 # https://www.linkedin.com/jobs/search/?keywords=python%20developer&location=San%20Jose%2C%20California%2C%20United%20States&distance=50 job_search_url = "https://www.linkedin.com/jobs/search/?" if job_title: job_search_url = job_search_url + "keywords=" + job_title if job_location: job_search_url = job_search_url + "&location=" + job_location if distance: job_search_url = job_search_url + "&distance=" + str(distance) temp_job_search_url = job_search_url + "&start=0" print(temp_job_search_url) time.sleep(10) if self.test_page( search_url=temp_job_search_url, page_no=1, css_selector_identifier="div.jobs-search-results ") == False: self.logger.info( "============Definitely no Result, Next Query==============") return 0 if random_start: trial = 0 st = 5 while True and trial < 5 and st > 1: st = random.randint(1, st - 1) temp_job_search_url = job_search_url + "&start=" + str(st * 25) if self.test_page(temp_job_search_url, st, "div.jobs-search-results"): break trial = trial + 1 else: st = 1 for page_no in list(range(st, st + max_pages)): try: temp_job_search_url = job_search_url + "&start=" + str(page_no) if page_no > st and st > 1: web_address_navigator(Settings, self.browser, temp_job_search_url) self.logger.info("Starting page: {}".format(page_no)) for jc in range(2, 11): sleep(1) self.browser.execute_script( "window.scrollTo(0, document.body.scrollHeight/" + str(jc) + "-100);") if len( self.browser.find_elements_by_css_selector( "div.jobs-search-results")) == 0: self.logger.info( "============Last Page Reached or asking for Premium membership==============" ) break for i in range( 0, len( self.browser.find_elements_by_css_selector( "div.jobs-search-results"))): print(i) except Exception as e: self.logger.error(e) input("Press Enter to continue...")
def follow_user(browser, track, login, userid_to_follow, button, blacklist, logger, logfolder, Settings): """ Follow a user either from the profile page or post page or dialog box """ # list of available tracks to follow in: ["profile", "post" "dialog"] # check action availability if quota_supervisor(Settings, "follows") == "jump": return False, "jumped" if track in ["profile", "post"]: if track == "profile": # check URL of the webpage, if it already is user's profile # page, then do not navigate to it again user_link = "https://www.facebook.com/{}/".format(userid_to_follow) web_address_navigator(browser, user_link, Settings) # find out CURRENT following status following_status, follow_button = \ get_following_status(browser, track, login, userid_to_follow, None, logger, logfolder) if following_status in ["Follow", "Follow Back"]: click_visibly(browser, Settings, follow_button) # click to follow follow_state, msg = verify_action(browser, "follow", track, login, userid_to_follow, None, logger, logfolder) if follow_state is not True: return False, msg elif following_status in ["Following", "Requested"]: if following_status == "Following": logger.info( "--> Already following '{}'!\n".format(userid_to_follow)) elif following_status == "Requested": logger.info("--> Already requested '{}' to follow!\n".format( userid_to_follow)) sleep(1) return False, "already followed" elif following_status in ["Unblock", "UNAVAILABLE"]: if following_status == "Unblock": failure_msg = "user is in block" elif following_status == "UNAVAILABLE": failure_msg = "user is inaccessible" logger.warning("--> Couldn't follow '{}'!\t~{}".format( userid_to_follow, failure_msg)) return False, following_status elif following_status is None: # TODO:BUG:2nd login has to be fixed with userid of loggedin user sirens_wailing, emergency_state = emergency_exit( browser, Settings, "https://www.facebook.com", login, login, logger, logfolder) if sirens_wailing is True: return False, emergency_state else: logger.warning( "--> Couldn't unfollow '{}'!\t~unexpected failure".format( userid_to_follow)) return False, "unexpected failure" elif track == "dialog": click_element(browser, Settings, button) sleep(3) # general tasks after a successful follow logger.info("--> Followed '{}'!".format(userid_to_follow.encode("utf-8"))) update_activity(Settings, 'follows') # get user ID to record alongside username user_id = get_user_id(browser, track, userid_to_follow, logger) logtime = datetime.now().strftime('%Y-%m-%d %H:%M') log_followed_pool(login, userid_to_follow, logger, logfolder, logtime, user_id) follow_restriction("write", userid_to_follow, None, logger) if blacklist['enabled'] is True: action = 'followed' add_user_to_blacklist(userid_to_follow, blacklist['campaign'], action, logger, logfolder) # get the post-follow delay time to sleep naply = get_action_delay("follow", Settings) sleep(naply) return True, "success"
def login_user(browser, username, userid, password, logger, logfolder, switch_language=True, bypass_suspicious_attempt=False, bypass_with_mobile=False): """Logins the user with the given username and password""" assert username, 'Username not provided' assert password, 'Password not provided' print(username, password) ig_homepage = "https://www.linkedin.com/login/" web_address_navigator(Settings, browser, ig_homepage) time.sleep(1) input_username_XP = '//*[@id="username"]' input_username = browser.find_element_by_xpath(input_username_XP) print('Entering username') (ActionChains(browser).move_to_element(input_username).click().send_keys( username).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) input_password = browser.find_elements_by_xpath('//*[@id="password"]') if not isinstance(password, str): password = str(password) print('Entering password') (ActionChains(browser).move_to_element( input_password[0]).click().send_keys(password).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) print('Submitting login_button') login_button = browser.find_element_by_xpath('//*[@type="submit"]') (ActionChains(browser).move_to_element(login_button).click().perform()) # update server calls update_activity(Settings) sleep(10) current_url = get_current_url(browser) if current_url != "https://www.linkedin.com/feed/": explicit_wait(browser, "PFL", [], logger, 5) current_url = get_current_url(browser) if current_url == "https://www.linkedin.com/feed/": return True else: return False
def unfollow_user(browser, track, username, userid, person, person_id, button, relationship_data, logger, logfolder, Settings): """ Unfollow a user either from the profile or post page or dialog box """ # list of available tracks to unfollow in: ["profile", "post" "dialog"] # check action availability if quota_supervisor(Settings, "unfollows") == "jump": return False, "jumped" if track in ["profile", "post"]: """ Method of unfollowing from a user's profile page or post page """ if track == "profile": user_link = "https://www.facebook.com/{}/".format(person) web_address_navigator(browser, user_link, Settings) # find out CURRENT follow status following_status, follow_button = get_following_status( browser, track, username, person, person_id, logger, logfolder) if following_status in ["Following", "Requested"]: click_element(browser, Settings, follow_button) # click to unfollow sleep(4) # TODO: use explicit wait here confirm_unfollow(browser) unfollow_state, msg = verify_action(browser, "unfollow", track, username, person, person_id, logger, logfolder) if unfollow_state is not True: return False, msg elif following_status in ["Follow", "Follow Back"]: logger.info("--> Already unfollowed '{}'! or a private user that " "rejected your req".format(person)) post_unfollow_cleanup(["successful", "uncertain"], username, person, relationship_data, person_id, logger, logfolder) return False, "already unfollowed" elif following_status in ["Unblock", "UNAVAILABLE"]: if following_status == "Unblock": failure_msg = "user is in block" elif following_status == "UNAVAILABLE": failure_msg = "user is inaccessible" logger.warning("--> Couldn't unfollow '{}'!\t~{}".format( person, failure_msg)) post_unfollow_cleanup("uncertain", username, person, relationship_data, person_id, logger, logfolder) return False, following_status elif following_status is None: sirens_wailing, emergency_state = emergency_exit( browser, Settings, username, userid, logger, logfolder) if sirens_wailing is True: return False, emergency_state else: logger.warning( "--> Couldn't unfollow '{}'!\t~unexpected failure".format( person)) return False, "unexpected failure" elif track == "dialog": """ Method of unfollowing from a dialog box """ click_element(browser, Settings, button) sleep(4) # TODO: use explicit wait here confirm_unfollow(browser) # general tasks after a successful unfollow logger.info("--> Unfollowed '{}'!".format(person)) update_activity(Settings, 'unfollows') post_unfollow_cleanup("successful", username, person, relationship_data, person_id, logger, logfolder) # get the post-unfollow delay time to sleep naply = get_action_delay("unfollow", Settings) sleep(naply) return True, "success"
def withdraw_old_invitations(self, skip_pages=10, sleep_delay=6): page_no = skip_pages while page_no < 100: page_no = page_no + 1 try: url = "https://www.linkedin.com/mynetwork/invitation-manager/sent/?page=" + str( page_no) web_address_navigator(Settings, self.browser, url) print("Starting page:", page_no) if self.browser.current_url == "https://www.linkedin.com/mynetwork/invitation-manager/sent/" or len( self.browser.find_elements_by_css_selector( "li.invitation-card div.pl5")) == 0: print("============Last Page Reached==============") break checked_in_page = 0 for i in range( 0, len( self.browser.find_elements_by_css_selector( "li.invitation-card div.pl5"))): try: res_item = self.browser.find_elements_by_css_selector( "li.invitation-card div.pl5")[i] try: link = res_item.find_element_by_css_selector( "div > a") profile_link = link.get_attribute("href") user_name = profile_link.split('/')[4] self.logger.info( "user_name : {}".format(user_name)) except Exception as e: print("Might be a stale profile", e) time = res_item.find_element_by_css_selector( "div > time") self.logger.info("time : {}".format(time.text)) check_button = res_item.find_element_by_css_selector( "div > div:nth-child(1) > input") check_status = check_button.get_attribute( "data-artdeco-is-focused") self.logger.info( "check_status : {}".format(check_status)) self.browser.execute_script("window.scrollTo(0, " + str((i + 1) * 104) + ");") if "month" in time.text: (ActionChains(self.browser).move_to_element( check_button).click().perform()) self.logger.info("check_button clicked") checked_in_page = checked_in_page + 1 delay_random = random.randint( ceil(sleep_delay * 0.42), ceil(sleep_delay * 0.57)) sleep(delay_random) except Exception as e: self.logger.error(e) if checked_in_page > 0: self.logger.info("Widraw to be pressed") try: self.browser.execute_script("window.scrollTo(0, 0);") withdraw_button = self.browser.find_element_by_css_selector( "ul > li.mn-list-toolbar__right-button > button") self.logger.info("withdraw_button : {}".format( withdraw_button.text)) if "Withdraw" in withdraw_button.text: (ActionChains(self.browser).move_to_element( withdraw_button).click().perform()) self.logger.info("withdraw_button clicked") page_no = page_no - 1 delay_random = random.randint( ceil(sleep_delay * 0.85), ceil(sleep_delay * 1.14)) sleep(delay_random) except Exception as e: print( "For some reason there is no withdraw_button inspite of checkings", e) else: self.logger.info("Nothing checked in this page") except Exception as e: self.logger.error(e) self.logger.info("============Next Page==============")
def login_user(browser, username, userid, password, logger, logfolder, switch_language=True, bypass_suspicious_attempt=False, bypass_with_mobile=False): """Logins the user with the given username and password""" assert username, 'Username not provided' assert password, 'Password not provided' print(username, password) ig_homepage = "https://accounts.google.com/ServiceLogin?continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Fhl%3Den%26feature%3Dcomment%26app%3Ddesktop%26next%3D%252Fall_comments%253Fv%253DLAr6oAKieHk%26action_handle_signin%3Dtrue&uilel=3&service=youtube&passive=true&hl=en" web_address_navigator(browser, ig_homepage, Settings) cookie_loaded = False # try to load cookie from username try: for cookie in pickle.load( open('{0}{1}_cookie.pkl'.format(logfolder, username), 'rb')): browser.add_cookie(cookie) cookie_loaded = True except (WebDriverException, OSError, IOError): print("Cookie file not found, creating cookie...") # include time.sleep(1) to prevent getting stuck on google.com time.sleep(1) web_address_navigator(browser, ig_homepage, Settings) reload_webpage(browser, Settings) # try: # profile_pic = browser.find_element_by_xpath('//header/div[8]/details/summary/img') # if profile_pic: # login_state = True # else: # login_state = False # except Exception as e: # print(e) # login_state = False # print('login_state:', login_state) # if login_state is True: # # dismiss_notification_offer(browser, logger) # return True # if user is still not logged in, then there is an issue with the cookie # so go create a new cookie.. if cookie_loaded: print("Issue with cookie for user {}. Creating " "new cookie...".format(username)) # wait until the 'username' input element is located and visible input_username_XP = '//*[@id="identifierId"]' # explicit_wait(browser, "VOEL", [input_username_XP, "XPath"], logger) input_username = browser.find_element_by_xpath(input_username_XP) print('moving to input_username') print('entering input_username') (ActionChains(browser).move_to_element(input_username).click().send_keys( username).perform()) sleep(1) (ActionChains(browser).send_keys(Keys.ENTER).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) # password input_password = browser.find_elements_by_xpath( "//*[@id='password']/div[1]/div/div[1]/input") if not isinstance(password, str): password = str(password) print('entering input_password') (ActionChains(browser).move_to_element( input_password[0]).click().send_keys(password).perform()) sleep(1) (ActionChains(browser).send_keys(Keys.ENTER).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) print('submitting (ie just pres enter)') (ActionChains(browser).send_keys(Keys.ENTER).perform()) # update server calls update_activity(Settings) sleep(1) # wait until page fully load explicit_wait(browser, "PFL", [], logger, 5) try: profile_pic = browser.find_element_by_xpath('//*[@id="img"]') if profile_pic: login_state = True print('logged in') pickle.dump( browser.get_cookies(), open('{0}{1}_cookie.pkl'.format(logfolder, username), 'wb')) else: login_state = False except Exception as e: print(e) login_state = False return login_state
def search_and_connect(self, query, connection_relationship_code, city_code, school_code=None, past_company=None, random_start=True, max_pages=10, max_connects=25, sleep_delay=6): """ search linkedin and connect from a given profile """ if quota_supervisor(Settings, "connects") == "jump": return 0 self.logger.info( "Searching for: query={}, connection_relationship_code={}, city_code={}, school_code={}" .format(query, connection_relationship_code, city_code, school_code)) connects = 0 prev_connects = -1 search_url = "https://www.linkedin.com/search/results/people/?" if connection_relationship_code: search_url = search_url + "&facetNetwork=" + connection_relationship_code if city_code: search_url = search_url + "&facetGeoRegion=" + city_code if school_code: search_url = search_url + "&facetSchool=" + school_code if past_company: search_url = search_url + "&facetPastCompany=" + past_company search_url = search_url + "&keywords=" + query search_url = search_url + "&origin=" + "FACETED_SEARCH" temp_search_url = search_url + "&page=1" print(temp_search_url) time.sleep(10) if self.test_page( search_url=temp_search_url, page_no=1, css_selector_identifier="div.search-result__wrapper") == False: self.logger.info( "============Definitely no Result, Next Query==============") return 0 if random_start: trial = 0 st = 5 while True and trial < 5 and st > 1: st = random.randint(1, st - 1) temp_search_url = search_url + "&page=" + str(st) if self.test_page(temp_search_url, st, "div.search-result__wrapper"): break trial = trial + 1 else: st = 1 for page_no in list(range(st, st + max_pages)): if prev_connects == connects: self.logger.info( "============Limits might have exceeded or all Invites pending from this page(let's exit either case)==============" ) break else: prev_connects = connects try: temp_search_url = search_url + "&page=" + str(page_no) if page_no > st and st > 1: web_address_navigator(Settings, self.browser, temp_search_url) self.logger.info("Starting page: {}".format(page_no)) for jc in range(2, 11): sleep(1) self.browser.execute_script( "window.scrollTo(0, document.body.scrollHeight/" + str(jc) + "-100);") if len( self.browser.find_elements_by_css_selector( "div.search-result__wrapper")) == 0: self.logger.info( "============Last Page Reached or asking for Premium membership==============" ) break for i in range( 0, len( self.browser.find_elements_by_css_selector( "div.search-result__wrapper"))): try: res_item = self.browser.find_elements_by_css_selector( "li.search-result div.search-entity div.search-result__wrapper" )[i] # div.search-result__actions div button") # pp.pprint(res_item.get_attribute('innerHTML')) link = res_item.find_element_by_css_selector("div > a") profile_link = link.get_attribute("href") self.logger.info("Profile : {}".format(profile_link)) user_name = profile_link.split('/')[4] # self.logger.info("user_name : {}".format(user_name)) name = res_item.find_element_by_css_selector( "h3 > span > span > span") #//span/span/span[1]") self.logger.info("Name : {}".format(name.text)) if connect_restriction("read", user_name, self.connect_times, self.logger): self.logger.info("already connected") continue try: connect_button = res_item.find_element_by_xpath( "//div[3]/div/button[text()='Connect']") self.logger.info( "Connect button found, connecting...") self.browser.execute_script( "var evt = document.createEvent('MouseEvents');" + "evt.initMouseEvent('click',true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0,null);" + "arguments[0].dispatchEvent(evt);", res_item.find_element_by_xpath( '//div[3]/div/button[text()="Connect"]')) self.logger.info("Clicked {}".format( connect_button.text)) sleep(2) except Exception: invite_sent_button = res_item.find_element_by_xpath( "//div[3]/div/button[text()='Invite Sent']") self.logger.info("Already {}".format( invite_sent_button.text)) continue try: modal = self.browser.find_element_by_css_selector( "div.modal-wormhole-content > div") if modal: try: sendnow_or_done_button = modal.find_element_by_xpath( "//div[1]/div/section/div/div[2]/button[2]" ) #text()='Send now']") self.logger.info( sendnow_or_done_button.text) if not (sendnow_or_done_button.text == 'Done' or sendnow_or_done_button.text == 'Send now'): raise Exception( "Send Now or Done button not found" ) if sendnow_or_done_button.is_enabled(): (ActionChains( self.browser).move_to_element( sendnow_or_done_button).click( ).perform()) self.logger.info("Clicked {}".format( sendnow_or_done_button.text)) connects = connects + 1 connect_restriction( "write", user_name, None, self.logger) try: # update server calls update_activity( Settings, 'connects') except Exception as e: self.logger.error(e) sleep(2) else: try: #TODO: input("find correct close XPATH") close_button = modal.find_element_by_xpath( "//div[1]/div/section/div/header/button" ) (ActionChains( self.browser).move_to_element( close_button).click(). perform()) print(sendnow_or_done_button.text, "disabled, clicked close") sleep(2) except Exception as e: print( "close_button not found, Failed with:", e) except Exception as e: print( "sendnow_or_done_button not found, Failed with:", e) else: self.logger.info("Popup not found") except Exception as e: print("Popup not found, Failed with:", e) try: new_popup_buttons = self.browser.find_elements_by_css_selector( "#artdeco-modal-outlet div.artdeco-modal-overlay div.artdeco-modal div.artdeco-modal__actionbar button.artdeco-button" ) gotit_button = new_popup_buttons[1] (ActionChains(self.browser).move_to_element( gotit_button).click().perform()) print(gotit_button.text, " clicked") sleep(2) except Exception as e: print("New Popup also not found, Failed with:", e) self.logger.info( "Connects sent in this iteration: {}".format( connects)) delay_random = random.randint(ceil(sleep_delay * 0.85), ceil(sleep_delay * 1.14)) sleep(delay_random) if connects >= max_connects: self.logger.info( "max_connects({}) for this iteration reached , Returning..." .format(max_connects)) return except Exception as e: self.logger.error(e) except Exception as e: self.logger.error(e) self.logger.info("============Next Page==============") return connects
def search_1stconnects_and_savetodb(self, query, city_code, school_code=None, past_company=None, random_start=True, max_pages=10, max_connects=25, sleep_delay=6): """ search linkedin and connect from a given profile """ self.logger.info( "Searching for: query={}, city_code={}, school_code={}".format( query, city_code, school_code)) search_url = "https://www.linkedin.com/search/results/people/?&facetNetwork=%5B%22F%22%5D" if city_code: search_url = search_url + "&facetGeoRegion=" + city_code if school_code: search_url = search_url + "&facetSchool=" + school_code if past_company: search_url = search_url + "&facetPastCompany=" + past_company search_url = search_url + "&keywords=" + query search_url = search_url + "&origin=" + "FACETED_SEARCH" for page_no in range(1, 101): try: temp_search_url = search_url + "&page=" + str(page_no) web_address_navigator(Settings, self.browser, temp_search_url) self.logger.info("Starting page: {}".format(page_no)) for jc in range(2, 11): sleep(1) self.browser.execute_script( "window.scrollTo(0, document.body.scrollHeight/" + str(jc) + ");") if len( self.browser.find_elements_by_css_selector( "div.search-result__wrapper")) == 0: self.logger.info( "============Last Page Reached or asking for Premium membership==============" ) break for i in range( 0, len( self.browser.find_elements_by_css_selector( "div.search-result__wrapper"))): try: res_item = self.browser.find_elements_by_css_selector( "li.search-result div.search-entity div.search-result__wrapper" )[i] link = res_item.find_element_by_css_selector("div > a") profile_link = link.get_attribute("href") user_name = profile_link.split('/')[4] self.logger.info("user_name : {}".format(user_name)) msg_button = res_item.find_element_by_xpath( "//div[3]/div/div/button[text()='Message']") print(msg_button.text, "present") if msg_button.text == "Message": connect_restriction("write", user_name, None, self.logger) self.logger.info( "saved {} to db".format(user_name)) except Exception as e: self.logger.error(e) except Exception as e: self.logger.error(e) self.logger.info("============Next Page==============")
def search_and_endorse(self, query, city_code, school_code, random_start=True, max_pages=3, max_endorsements=25, sleep_delay=6): """ search linkedin and endose few first connections """ if quota_supervisor(Settings, "connects") == "jump": return #False, "jumped" print("Searching for: ", query, city_code, school_code) search_url = "https://www.linkedin.com/search/results/people/?" if city_code: search_url = search_url + "&facetGeoRegion=" + city_code if school_code: search_url = search_url + "&facetSchool=" + school_code search_url = search_url + "&facetNetwork=%5B%22F%22%5D" search_url = search_url + "&keywords=" + query search_url = search_url + "&origin=" + "FACETED_SEARCH" if random_start: trial = 0 while True and trial < 3: st = random.randint(1, 3) temp_search_url = search_url + "&page=" + str(st) web_address_navigator(Settings, self.browser, temp_search_url) self.logger.info("Testing page:".format(st)) result_items = self.browser.find_elements_by_css_selector( "div.search-result__wrapper") if len(result_items) > 0: break trial = trial + 1 else: st = 1 connects = 0 for page_no in list(range(st, st + 1)): collected_profile_links = [] try: temp_search_url = search_url + "&page=" + str(page_no) if page_no > st and st > 1: web_address_navigator(Settings, self.browser, temp_search_url) self.logger.info("Starting page: {}".format(page_no)) for jc in range(2, 11): sleep(1) self.browser.execute_script( "window.scrollTo(0, document.body.scrollHeight/" + str(jc) + "-100);") result_items = self.browser.find_elements_by_css_selector( "div.search-result__wrapper") # print(result_items) for result_item in result_items: try: link = result_item.find_element_by_css_selector( "div > a") self.logger.info("Profile : {}".format( link.get_attribute("href"))) collected_profile_links.append( link.get_attribute("href")) name = result_item.find_element_by_css_selector( "h3 > span > span > span") self.logger.info("Name : {}".format(name.text)) except Exception as e: self.logger.error(e) except Exception as e: self.logger.error(e) for collected_profile_link in collected_profile_links: self.endorse(collected_profile_link, sleep_delay=sleep_delay) connects = connects + 1 if connects >= max_endorsements: self.logger.info( "max_endorsements({}) for this iteration reached , Returning..." .format(max_endorsements)) return self.logger.info("============Next Page==============")
def verify_action(browser, action, track, username, person, person_id, logger, logfolder): """ Verify if the action has succeeded """ # currently supported actions are follow & unfollow retry_count = 0 if action in ["follow", "unfollow"]: # assuming button_change testing is relevant to those actions only button_change = False if action == "follow": post_action_text_correct = ["Following", "Requested"] post_action_text_fail = ["Follow", "Follow Back", "Unblock"] elif action == "unfollow": post_action_text_correct = ["Follow", "Follow Back", "Unblock"] post_action_text_fail = ["Following", "Requested"] while True: # count retries at beginning retry_count += 1 # find out CURRENT follow status (this is safe as the follow button is before others) following_status, follow_button = get_following_status( browser, track, username, person, person_id, logger, logfolder) if following_status in post_action_text_correct: button_change = True elif following_status in post_action_text_fail: button_change = False else: logger.error( "Hey! Last {} is not verified out of an unexpected " "failure!".format(action)) return False, "unexpected" if button_change: break else: if retry_count == 1: reload_webpage(browser) elif retry_count == 2: # handle it! # try to do the action one more time! click_visibly(browser, follow_button) if action == "unfollow": confirm_unfollow(browser) sleep(4) elif retry_count == 3: logger.warning("Phew! Last {0} is not verified." "\t~'{1}' might be temporarily blocked " "from {0}ing\n".format(action, username)) sleep(210) return False, "temporary block" if retry_count == 2: logger.info( "Last {} is verified after reloading the page!".format(action)) return True, "success"
def bypass_suspicious_login(browser, bypass_with_mobile): """Bypass suspicious loggin attempt verification. This should be only enabled when there isn't available cookie for the username, otherwise it will and shows "Unable to locate email or phone button" message, folollowed by CRITICAL - Wrong login data!""" # close sign up Facebook modal if available try: close_button = browser.find_element_by_xpath("[text()='Close']") (ActionChains(browser).move_to_element(close_button).click().perform()) # update server calls update_activity(Settings) except NoSuchElementException: pass try: # click on "This was me" button if challenge page was called this_was_me_button = browser.find_element_by_xpath( "//button[@name='choice'][text()='This Was Me']") (ActionChains(browser).move_to_element( this_was_me_button).click().perform()) # update server calls update_activity(Settings) except NoSuchElementException: # no verification needed pass try: choice = browser.find_element_by_xpath("//label[@for='choice_1']").text except NoSuchElementException: try: choice = browser.find_element_by_xpath( "//label[@class='_q0nt5']").text except Exception: try: choice = browser.find_element_by_xpath( "//label[@class='_q0nt5 _a7z3k']").text except Exception: print("Unable to locate email or phone button, maybe " "bypass_suspicious_login=True isn't needed anymore.") return False if bypass_with_mobile: choice = browser.find_element_by_xpath("//label[@for='choice_0']").text mobile_button = browser.find_element_by_xpath( "//label[@for='choice_0']") (ActionChains(browser).move_to_element( mobile_button).click().perform()) sleep(5) send_security_code_button = browser.find_element_by_xpath( "//button[text()='Send Security Code']") (ActionChains(browser).move_to_element( send_security_code_button).click().perform()) # update server calls update_activity(Settings) print('Facebook detected an unusual login attempt') print('A security code was sent to your {}'.format(choice)) security_code = input('Type the security code here: ') security_code_field = browser.find_element_by_xpath( ("//input[@id='security_code']")) (ActionChains(browser).move_to_element( security_code_field).click().send_keys(security_code).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) submit_security_code_button = browser.find_element_by_xpath( "//button[text()='Submit']") (ActionChains(browser).move_to_element( submit_security_code_button).click().perform()) # update server calls update_activity(Settings) try: sleep(5) # locate wrong security code message wrong_login = browser.find_element_by_xpath( ("//p[text()='Please check the code we sent you and try " "again.']")) if wrong_login is not None: print(('Wrong security code! Please check the code Facebook' 'sent you and try again.')) except NoSuchElementException: # correct security code pass
def login_user(browser, username, password, userid, logger, logfolder): """Logins the user with the given username and password""" assert username, 'Username not provided' assert password, 'Password not provided' print(username, password) homepage = "https://www.medium.com/" web_address_navigator(browser, homepage, Settings) cookie_loaded = False # try to load cookie from username try: for cookie in pickle.load( open('{0}{1}_cookie.pkl'.format(logfolder, username), 'rb')): browser.add_cookie(cookie) cookie_loaded = True except (WebDriverException, OSError, IOError): print("Cookie file not found, creating cookie...") # include time.sleep(1) to prevent getting stuck on google.com time.sleep(1) web_address_navigator(browser, homepage, Settings) reload_webpage(browser, Settings) # if user is still not logged in, then there is an issue with the cookie # so go create a new cookie.. # cookie has been LOADED, so the user SHOULD be logged in # check if the user IS logged in if cookie_loaded: login_state = check_authorization(browser, Settings, "https://www.medium.com", username, userid, "activity counts", logger, logfolder, True) print('check_authorization:', login_state) if login_state is True: # dismiss_notification_offer(browser, logger) return True else: print("Issue with cookie for user {}. Creating " "new cookie...".format(username)) input_username_XP = '//div[2]/div[1]/input[@name="email"]' input_usernames = browser.find_elements_by_xpath( input_username_XP) #TODO : Two tags found just take the last one print('moving to input_username') print('entering input_username: {}'.format(username)) #email login doesn't reprompt (ActionChains(browser).move_to_element( input_usernames[-1]).click().send_keys(username).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) # password input_passeord_XP = '//div[2]/div[2]/input[@name="password"]' input_passwords = browser.find_elements_by_xpath(input_passeord_XP) print('entering input_password') (ActionChains(browser).move_to_element( input_passwords[-1]).click().send_keys(password).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) print('submitting login_button') login_button_XP = '//div[2]/div[3]/input' login_button = browser.find_element_by_xpath(login_button_XP) (ActionChains(browser).move_to_element(login_button).click().perform()) # update server calls update_activity(Settings) sleep(2) # wait until page fully load explicit_wait(browser, "PFL", [], logger, 5) # Check if user is logged-in (If there's two 'nav' elements) login_state = check_authorization(browser, Settings, "https://www.medium.com/login", username, userid, "activity counts", logger, logfolder, True) print('check_authorization again:', login_state) return login_state
def get_links_for_username(browser, username, person, amount, logger, logfolder, randomize=False, media=None, taggedImages=False): """Fetches the number of links specified by amount and returns a list of links""" if media is None: # All known media types media = ['', 'Post', 'Video'] elif media == 'Photo': # Include posts with multiple images in it media = ['', 'Post'] else: # Make it an array to use it in the following part media = [media] logger.info('Getting {} image list...'.format(person)) user_link = "https://www.facebook.com/{}/".format(person) if taggedImages: user_link = user_link + 'tagged/' # Check URL of the webpage, if it already is user's profile page, # then do not navigate to it again web_address_navigator(browser, user_link, logger, Settings) if "Page Not Found" in browser.title: logger.error( 'Facebook error: The link you followed may be broken, or the ' 'page may have been removed...') return False # if private user, we can get links only if we following following, follow_button = get_following_status(browser, 'profile', username, person, None, logger, logfolder) if following == 'Following': following = True is_private = is_private_profile(Settings, browser, logger, following) if (is_private is None) or (is_private is True and not following) or (following == 'Blocked'): return False # Get links links = [] main_elem = browser.find_element_by_tag_name('article') posts_count = get_number_of_posts(browser) attempt = 0 if posts_count is not None and amount > posts_count: logger.info( "You have requested to get {} posts from {}'s profile page BUT" " there only {} posts available :D".format(amount, person, posts_count)) amount = posts_count while len(links) < amount: initial_links = links browser.execute_script( "window.scrollTo(0, document.body.scrollHeight);") # update server calls after a scroll request update_activity(Settings) sleep(0.66) # using `extend` or `+=` results reference stay alive which affects # previous assignment (can use `copy()` for it) links = links + get_links(browser, person, logger, media, main_elem) links = sorted(set(links), key=links.index) if len(links) == len(initial_links): if attempt >= 7: logger.info( "There are possibly less posts than {} in {}'s profile " "page!".format(amount, person)) break else: attempt += 1 else: attempt = 0 if randomize is True: random.shuffle(links) return links[:amount]
def login_user(browser, username, userid, password, logger, logfolder, switch_language=True, bypass_suspicious_attempt=False, bypass_with_mobile=False): """Logins the user with the given username and password""" assert username, 'Username not provided' assert password, 'Password not provided' print(username, password) ig_homepage = "https://www.facebook.com" web_address_navigator(browser, ig_homepage, Settings) cookie_loaded = False # try to load cookie from username try: for cookie in pickle.load( open('{0}{1}_cookie.pkl'.format(logfolder, username), 'rb')): browser.add_cookie(cookie) cookie_loaded = True except (WebDriverException, OSError, IOError): print("Cookie file not found, creating cookie...") # include time.sleep(1) to prevent getting stuck on google.com time.sleep(1) # changes facebook website language to english to use english xpaths if switch_language: links = browser.find_elements_by_xpath('//*[@id="pageFooter"]/ul/li') for link in links: if link.get_attribute('title') == "English (UK)": click_element(browser, Settings, link) web_address_navigator(browser, ig_homepage, Settings) reload_webpage(browser, Settings) # cookie has been LOADED, so the user SHOULD be logged in # check if the user IS logged in login_state = check_authorization(browser, Settings, "https://www.facebook.com/", username, userid, "activity counts", logger, logfolder, True) print('check_authorization:', login_state) if login_state is True: # dismiss_notification_offer(browser, logger) return True # if user is still not logged in, then there is an issue with the cookie # so go create a new cookie.. if cookie_loaded: print("Issue with cookie for user {}. Creating " "new cookie...".format(username)) # # Check if the first div is 'Create an Account' or 'Log In' # login_elem = browser.find_element_by_xpath( # '//*[@id="email"]' # ) # if login_elem is not None: # try: # (ActionChains(browser) # .move_to_element(login_elem) # .click() # .perform()) # except MoveTargetOutOfBoundsException: # login_elem.click() # # update server calls # update_activity(Settings) # Enter username and password and logs the user in # Sometimes the element name isn't 'Username' and 'Password' # (valid for placeholder too) # wait until it navigates to the login page # login_page_title = "Login" # explicit_wait(browser, "TC", login_page_title, logger) # wait until the 'username' input element is located and visible input_username_XP = '//*[@id="email"]' # explicit_wait(browser, "VOEL", [input_username_XP, "XPath"], logger) input_username = browser.find_element_by_xpath(input_username_XP) print('moving to input_username') print('entering input_username') (ActionChains(browser).move_to_element(input_username).click().send_keys( username).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) # password input_password = browser.find_elements_by_xpath('//*[@id="pass"]') if not isinstance(password, str): password = str(password) print('entering input_password') (ActionChains(browser).move_to_element( input_password[0]).click().send_keys(password).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) print('submitting login_button') login_button = browser.find_element_by_xpath('//*[@type="submit"]') (ActionChains(browser).move_to_element(login_button).click().perform()) # update server calls update_activity(Settings) sleep(1) # dismiss_get_app_offer(browser, logger) # dismiss_notification_offer(browser, logger) if bypass_suspicious_attempt is True: bypass_suspicious_login(browser, bypass_with_mobile) # wait until page fully load # explicit_wait(browser, "PFL", [], logger, 5) # Check if user is logged-in (If there's two 'nav' elements) nav = browser.find_elements_by_xpath('//div[@role="navigation"]') if len(nav) == 2: # create cookie for username print('logged in') pickle.dump( browser.get_cookies(), open('{0}{1}_cookie.pkl'.format(logfolder, username), 'wb')) return True else: return False
def login_user( browser, username, userid, password, logger, logfolder, switch_language=True, bypass_suspicious_attempt=False, bypass_with_mobile=False, ): """Logins the user with the given username and password""" assert username, "Username not provided" assert password, "Password not provided" ig_homepage = "https://www.facebook.com" web_address_navigator(browser, ig_homepage, logger, Settings) cookie_loaded = False # try to load cookie from username try: for cookie in pickle.load( open("{0}{1}_cookie.pkl".format(logfolder, username), "rb")): browser.add_cookie(cookie) cookie_loaded = True except (WebDriverException, OSError, IOError): logger.info("Cookie file not found, creating cookie...") # include time.sleep(1) to prevent getting stuck on google.com time.sleep(1) # changes facebook website language to english to use english xpaths if switch_language: links = browser.find_elements_by_xpath('//*[@id="pageFooter"]/ul/li') for link in links: if link.get_attribute("title") == "English (UK)": click_element(browser, Settings, link) web_address_navigator(browser, ig_homepage, logger, Settings) reload_webpage(browser, Settings) # cookie has been LOADED, so the user SHOULD be logged in # check if the user IS logged in login_state = check_authorization( browser, Settings, "https://www.facebook.com/", username, userid, "activity counts", logger, logfolder, True, ) logger.info("check_authorization: {}".format(login_state)) if login_state is True: # dismiss_notification_offer(browser, logger) return True # if user is still not logged in, then there is an issue with the cookie # so go create a new cookie.. if cookie_loaded: logger.info( "Issue with cookie for user {}. Creating new cookie...".format( username)) # wait until the 'username' input element is located and visible input_username_XP = '//*[@id="email"]' # explicit_wait(browser, "VOEL", [input_username_XP, "XPath"], logger) input_username = browser.find_element_by_xpath(input_username_XP) logger.info("moving to input_username") logger.info("entering input_username") (ActionChains(browser).move_to_element(input_username).click().send_keys( username).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) # password input_password = browser.find_elements_by_xpath('//*[@id="pass"]') if not isinstance(password, str): password = str(password) logger.info("entering input_password") (ActionChains(browser).move_to_element( input_password[0]).click().send_keys(password).perform()) # update server calls for both 'click' and 'send_keys' actions for i in range(2): update_activity(Settings) sleep(1) logger.info("submitting login_button") login_button = browser.find_element_by_xpath('//*[@type="submit"]') (ActionChains(browser).move_to_element(login_button).click().perform()) # update server calls update_activity(Settings) sleep(1) if bypass_suspicious_attempt is True: bypass_suspicious_login(browser, bypass_with_mobile, logger) # Check if user is logged-in (If there's two 'nav' elements) nav = browser.find_elements_by_xpath('//div[@role="navigation"]') if len(nav) == 2: # create cookie for username logger.info("logged in") pickle.dump( browser.get_cookies(), open("{0}{1}_cookie.pkl".format(logfolder, username), "wb"), ) return True else: return False