Пример #1
0
def likers_from_post(browser, logger, Selectors, amount=20):
    """ Get the list of users from the 'Likes' dialog of a photo """

    liked_counter_button = '//form/div/div/div/div/div/span/span/a[@role="button"]'

    try:
        liked_this = browser.find_elements_by_xpath(liked_counter_button)
        element_to_click = liked_this[0]

        sleep(1)
        click_element(browser, Settings, element_to_click)
        logger.info("opening likes")
        # update server calls
        # update_activity(Settings)

        sleep(1)

        # get a reference to the 'Likes' dialog box
        dialog = browser.find_element_by_xpath(
            Selectors.likes_dialog_body_xpath)

        # scroll down the page
        previous_len = -1
        browser.execute_script(
            "arguments[0].scrollTop = arguments[0].scrollHeight", dialog)
        update_activity(Settings)
        sleep(1)

        start_time = time.time()
        user_list = []

        while (not user_list or (len(user_list) != previous_len) and
               (len(user_list) < amount)):

            previous_len = len(user_list)
            scroll_bottom(browser, dialog, 2)

            user_list = get_users_from_dialog(user_list, dialog, logger)

            # write & update records at Progress Tracker
            progress_tracker(len(user_list), amount, start_time, None)

            if previous_len + 10 >= amount:
                logger.info("Scrolling finished")
                sleep(1)
                break

        random.shuffle(user_list)
        sleep(1)

        close_dialog_box(browser)

        logger.info("Got {} likers shuffled randomly whom you can follow:\n{}"
                    "\n".format(len(user_list), user_list))
        return user_list

    except Exception as exc:
        logger.Error("Some problem occured!\n\t{}".format(
            str(exc).encode("utf-8")))
        return []
Пример #2
0
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"
Пример #3
0
def open_comment_section(browser, logger):
    missing_comment_elem_warning = (
        "--> Comment Button Not Found!"
        "\t~may cause issues with browser windows of smaller widths")

    comment_elem = browser.find_elements_by_xpath(
        "//button/span[@aria-label='Comment']")

    if len(comment_elem) > 0:
        try:
            click_element(browser, Settings, comment_elem[0])

        except WebDriverException:
            logger.warning(missing_comment_elem_warning)

    else:
        logger.warning(missing_comment_elem_warning)
Пример #4
0
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)
Пример #5
0
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"
Пример #6
0
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"
Пример #7
0
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
Пример #8
0
def likers_from_post(browser, logger, Selectors, amount=20):
    """ Get the list of users from the 'Likes' dialog of a photo """

    liked_counter_button = \
        '//form/div/div/div/div/div/span/span/a[@role="button"]'

    try:
        liked_this = browser.find_elements_by_xpath(liked_counter_button)
        element_to_click = liked_this[0]
        # print('element_to_click:', element_to_click)
        # likers = []

        # for liker in liked_this:
        #     if " like this" not in liker.text:
        #         likers.append(liker.text)

        # if check_exists_by_xpath(browser, liked_counter_button):
        #     if " others" in liked_this[-1].text:
        #         element_to_click = liked_this[-1]

        #     elif " likes" in liked_this[0].text:
        #         element_to_click = liked_this[0]

        #     else:
        #         print("Few likes, not guaranteed you don't follow these"
        #               " likers already.\nGot photo likers: {}\n"
        #               .format(likers))
        #         return likers

        # else:
        #     print("Couldn't find liked counter button. May be a video.")
        #     print("Moving on..")
        #     return []

        sleep(1)
        click_element(browser, Settings, element_to_click)
        print("opening likes")
        # update server calls
        # update_activity(Settings)

        sleep(1)

        # get a reference to the 'Likes' dialog box
        dialog = browser.find_element_by_xpath(
            Selectors.likes_dialog_body_xpath)

        # scroll down the page
        previous_len = -1
        browser.execute_script(
            "arguments[0].scrollTop = arguments[0].scrollHeight", dialog)
        update_activity(Settings)
        sleep(1)

        start_time = time.time()
        user_list = []

        while (not user_list or (len(user_list) != previous_len) and
               (len(user_list) < amount)):

            previous_len = len(user_list)
            scroll_bottom(browser, dialog, 2)

            user_list = get_users_from_dialog(user_list, dialog, logger)
            # print('user_list (loop):')
            # print(user_list)

            # write & update records at Progress Tracker
            progress_tracker(len(user_list), amount, start_time, None)

            if previous_len + 10 >= amount:
                print("\nScrolling finished")
                sleep(1)
                break

        print('\n')
        # print('user_list:')
        # print(user_list)
        random.shuffle(user_list)
        sleep(1)

        close_dialog_box(browser)

        print("Got {} likers shuffled randomly whom you can follow:\n{}"
              "\n".format(len(user_list), user_list))
        return user_list

    except Exception as exc:
        print("Some problem occured!\n\t{}".format(str(exc).encode("utf-8")))
        return []
Пример #9
0
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