def get_post_urls_from_profile(browser, userid, logger, links_to_return_amount=1, randomize=True): try: logger.info("Getting likers from user: {}".format(userid)) web_address_navigator(browser, 'https://www.facebook.com/' + userid + '/', logger, Settings) sleep(1) posts_a_elems = browser.find_elements_by_xpath( "//div/div/div/div/div/div/div/div/div/div/span/span/a") links = [] for post_element in posts_a_elems: try: post_url = post_element.get_attribute("href") # TODO: "/posts/" doesnt cover all types # "/videos/", "/photos/" to be implemented later if "/posts/" in post_url: links.append(post_url) except Exception as es: logger.error(es) if randomize is True: logger.info("shuffling links") random.shuffle(links) logger.info("Got {}, returning {} links: {}".format( len(links), min(links_to_return_amount, len(links)), links[:links_to_return_amount] )) sleep(1) return links[:links_to_return_amount] except Exception as e: logger.error("Error: Couldnt get pictures links.".format(e)) return []
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 get_following_status(browser, track, username, person, person_id, logger, logfolder): """ Verify if you are following the user in the loaded page """ if track == "profile": ig_homepage = "https://www.medium.com/" web_address_navigator(browser, ig_homepage + person, Settings) follow_button_XP = ( '//*[@id="page-container"]/div/div/ul/li/div/div/span/button[@type="button"]/span[text()="Follow"]' ) failure_msg = "--> Unable to detect the following status of '{}'!" # user_inaccessible_msg = ( # "Couldn't access the profile page of '{}'!\t~might have changed the" # " username".format(person)) # check if the page is available # valid_page = is_page_available(browser, logger, Settings) # if not valid_page: # logger.warning(user_inaccessible_msg) # person_new = verify_username_by_id(browser, # username, # person, # None, # logger, # logfolder) # if person_new: # web_address_navigator( browser, ig_homepage + person_new, Settings) # valid_page = is_page_available(browser, logger, Settings) # if not valid_page: # logger.error(failure_msg.format(person_new.encode("utf-8"))) # return "UNAVAILABLE", None # else: # logger.error(failure_msg.format(person.encode("utf-8"))) # return "UNAVAILABLE", None # wait until the follow button is located and visible, then get it follow_button = explicit_wait(browser, "VOEL", [follow_button_XP, "XPath"], logger, 7, False) logger.info("follow_button = {}".format(follow_button)) if not follow_button: browser.execute_script("location.reload()") update_activity(Settings) follow_button = explicit_wait(browser, "VOEL", [follow_button_XP, "XPath"], logger, 14, False) logger.info("follow_button retried = {}".format(follow_button)) if not follow_button: # cannot find the any of the expected buttons logger.error(failure_msg.format(person.encode("utf-8"))) return None, None # get follow status following_status = follow_button.text logger.info("following_status returned = {}".format(following_status)) return following_status, follow_button
def users_liked(browser, post_url, logger, amount=100): post_likers = [] try: web_address_navigator(browser, post_url, logger, Settings) post_likers = likers_from_post(browser, logger, amount) sleep(2) except NoSuchElementException: logger.info('Could not get information from post: {}, nothing to return'.format(post_url)) return post_likers
def friend_user(browser, track, login, userid_to_friend, times, blacklist, logger, logfolder): """ Friend a user either from the profile page or post page or dialog box """ # list of available tracks to friend in: ["profile", "post" "dialog"] # check action availability if quota_supervisor(Settings, "friends") == "jump": return False, "jumped" # check URL of the webpage, if it already is user's profile # page, then do not navigate to it again if friend_restriction("read", userid_to_friend, 1, logger): logger.info("Already connected {} or more times".format(times)) return False, "already friended" user_link = "https://www.facebook.com/{}/".format(userid_to_friend) web_address_navigator(browser, user_link, logger, Settings) # find out CURRENT friending status friending_status, friend_button = get_friending_status( browser, track, login, userid_to_friend, None, logger, logfolder) logger.info(friending_status) if friending_status in ["Add Friend"]: click_visibly(browser, Settings, friend_button) # click to friend friend_state, msg = verify_action(browser, "friend", track, login, userid_to_friend, None, logger, logfolder) if friend_state is not True: return False, msg elif friending_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://facebook.com", login, login, logger, logfolder) if sirens_wailing is True: return False, emergency_state else: logger.warning( "--> Add Friend button not present '{}'!\t~unexpected failure". format(userid_to_friend)) return False, "unexpected failure" # general tasks after a successful friend logger.info("--> Friended '{}'!".format(userid_to_friend.encode("utf-8"))) update_activity(Settings, 'friendeds') logtime = datetime.now().strftime('%Y-%m-%d %H:%M') log_friended_pool(login, userid_to_friend, logger, logfolder, logtime, userid_to_friend) friend_restriction("write", userid_to_friend, None, logger) return True, "success"
def get_friending_status(browser, track, username, person, person_id, logger, logfolder): """ Verify if you are friending the user in the loaded page """ if track == "profile": ig_homepage = "https://www.facebook.com/" web_address_navigator( browser, ig_homepage + person, Settings) friend_button_XP = ("//div[@id='fbTimelineHeadline']/div/div/div/div/button[@type='button'][text()='Add Friend']") failure_msg = "--> Unable to detect the friending status of '{}'!" user_inaccessible_msg = ( "Couldn't access the profile page of '{}'!\t~might have changed the" " username".format(person)) # check if the page is available valid_page = is_page_available(browser, logger, Settings) if not valid_page: logger.warning(user_inaccessible_msg) person_new = verify_username_by_id(browser, username, person, None, logger, logfolder) if person_new: web_address_navigator( browser, ig_homepage + person_new, Settings) valid_page = is_page_available(browser, logger, Settings) if not valid_page: logger.error(failure_msg.format(person_new.encode("utf-8"))) return "UNAVAILABLE", None else: logger.error(failure_msg.format(person.encode("utf-8"))) return "UNAVAILABLE", None # wait until the friend button is located and visible, then get it friend_button = explicit_wait(browser, "VOEL", [friend_button_XP, "XPath"], logger, 7, False) if not friend_button: browser.execute_script("location.reload()") update_activity(Settings) friend_button = explicit_wait(browser, "VOEL", [friend_button_XP, "XPath"], logger, 14, False) if not friend_button: # cannot find the any of the expected buttons logger.error(failure_msg.format(person.encode("utf-8"))) return None, None # get friend status friending_status = friend_button.text return friending_status, friend_button
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 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, 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 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