Browse Source

Merge pull request #23 from weskerfoot/remove-likes

[WIP] Remove likes & various improvements
pull/44/head
Wesley Kerfoot 6 years ago
committed by GitHub
parent
commit
9513214153
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 22
      README.md
  2. 106
      deletefb/deletefb.py
  3. 0
      deletefb/tools/__init__.py
  4. 3
      deletefb/tools/common.py
  5. 8
      deletefb/tools/likes.py
  6. 70
      deletefb/tools/login.py
  7. 41
      deletefb/tools/wall.py

22
README.md

@ -38,27 +38,19 @@ would if you had installed it from PyPI.
everything. You may safely minimize the chrome window without breaking it. everything. You may safely minimize the chrome window without breaking it.
## 2FA ## 2FA
* If you have 2-Factor Auth configured then the script will pause for 20 * It is recommended that you disable Two-Factor Authentication tempoprarily
while you are running the script, in order to get the best experience.
* If you do have 2-Factor Auth configured then the script will pause for 20
seconds to allow you to enter your code and log in. seconds to allow you to enter your code and log in.
* You may also pass in a code by using the `-F` argument, e.g. `-F 111111`.
## Headless mode ## Headless mode
* The tool supports running Chrome in headless mode with the `--headless` * The tool supports running Chrome in headless mode with the `--headless`
option, which may be preferable if you plan on running it in the background. option, which may be preferable if you plan on running it in the background.
## How To Install Python ## Bugs
### MacOS
See [this link](https://docs.python-guide.org/starting/install3/osx/) for
instructions on installing with Brew.
### Linux
Use your native package manager
### Windows
See [this link](https://www.howtogeek.com/197947/how-to-install-python-on-windows/), but I make no guarantees that Selenium will actually work as I have not tested it.
### Bugs
If it stops working or otherwise crashes, delete the latest post manually and If it stops working or otherwise crashes, delete the latest post manually and
start it again after waiting a minute. I make no guarantees that it will work start it again after waiting a minute. I make no guarantees that it will work

106
deletefb/deletefb.py

@ -1,16 +1,10 @@
#! /usr/bin/env python #! /usr/bin/env python
import argparse import argparse
import time
import getpass import getpass
from seleniumrequests import Chrome from deletefb.tools.login import login
from selenium.webdriver.common.action_chains import ActionChains import deletefb.tools.wall as wall
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
MAX_POSTS = 5000
SELENIUM_EXCEPTIONS = (NoSuchElementException, StaleElementReferenceException)
def run_delete(): def run_delete():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
@ -63,7 +57,7 @@ def run_delete():
args_user_password = args.password or getpass.getpass('Enter your password: ') args_user_password = args.password or getpass.getpass('Enter your password: ')
delete_posts( driver = login(
user_email_address=args.email, user_email_address=args.email,
user_password=args_user_password, user_password=args_user_password,
user_profile_url=args.profile_url, user_profile_url=args.profile_url,
@ -71,99 +65,7 @@ def run_delete():
two_factor_token=args.two_factor_token two_factor_token=args.two_factor_token
) )
def delete_posts(user_email_address, wall.delete_posts(driver)
user_password,
user_profile_url,
is_headless,
two_factor_token):
"""
user_email_address: str Your Email
user_password: str Your password
user_profile_url: str Your profile URL
"""
# The Chrome driver is required because Gecko was having issues
chrome_options = Options()
prefs = {"profile.default_content_setting_values.notifications": 2, 'disk-cache-size': 4096}
chrome_options.add_experimental_option("prefs", prefs)
chrome_options.add_argument("start-maximized")
if is_headless:
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('log-level=2')
driver = Chrome(options=chrome_options)
driver.implicitly_wait(10)
driver.get("https://facebook.com")
email = "email"
password = "pass"
login = "loginbutton"
approvals_code = "approvals_code"
emailelement = driver.find_element_by_name(email)
passwordelement = driver.find_element_by_name(password)
emailelement.send_keys(user_email_address)
passwordelement.send_keys(user_password)
loginelement = driver.find_element_by_id(login)
loginelement.click()
if "two-factor authentication" in driver.page_source.lower():
if two_factor_token:
twofactorelement = driver.find_element_by_name(approvals_code)
twofactorelement.send_keys(two_factor_token)
#Submits after the code is passed into the form, does not validate 2FA code.
contelement = driver.find_element_by_id("checkpointSubmitButton")
contelement.click()
#Defaults to saving this new browser, this occurs on each new automated login.
save_browser = driver.find_element_by_id("checkpointSubmitButton")
save_browser.click()
else:
# Allow time to enter 2FA code
print("Pausing to enter 2FA code")
time.sleep(20)
print("Continuing execution")
driver.get(user_profile_url)
for _ in range(MAX_POSTS):
post_button_sel = "_4xev"
while True:
try:
timeline_element = driver.find_element_by_class_name(post_button_sel)
actions = ActionChains(driver)
actions.move_to_element(timeline_element).click().perform()
menu = driver.find_element_by_css_selector("#globalContainer > div.uiContextualLayerPositioner.uiLayer > div")
actions.move_to_element(menu).perform()
try:
delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"FeedDeleteOption\"]")
except SELENIUM_EXCEPTIONS:
delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"HIDE_FROM_TIMELINE\"]")
actions.move_to_element(delete_button).click().perform()
confirmation_button = driver.find_element_by_class_name("layerConfirm")
# Facebook would not let me get focus on this button without some custom JS
driver.execute_script("arguments[0].click();", confirmation_button)
except SELENIUM_EXCEPTIONS:
continue
else:
break
# Required to sleep the thread for a bit after using JS to click this button
time.sleep(5)
driver.refresh()
if __name__ == "__main__": if __name__ == "__main__":
run_delete() run_delete()

0
deletefb/tools/__init__.py

3
deletefb/tools/common.py

@ -0,0 +1,3 @@
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
SELENIUM_EXCEPTIONS = (NoSuchElementException, StaleElementReferenceException)

8
deletefb/tools/likes.py

@ -0,0 +1,8 @@
from selenium.webdriver.common.action_chains import ActionChains
from .common import SELENIUM_EXCEPTIONS
def unlike_pages(driver):
"""
Unlike all pages
"""
return

70
deletefb/tools/login.py

@ -0,0 +1,70 @@
import time
from selenium.webdriver.chrome.options import Options
from seleniumrequests import Chrome
def login(user_email_address,
user_password,
user_profile_url,
is_headless,
two_factor_token):
"""
Attempts to log into Facebook
Returns a driver object
user_email_address: str Your Email
user_password: str Your password
user_profile_url: str Your profile URL
"""
# The Chrome driver is required because Gecko was having issues
chrome_options = Options()
prefs = {"profile.default_content_setting_values.notifications": 2, 'disk-cache-size': 4096}
chrome_options.add_experimental_option("prefs", prefs)
chrome_options.add_argument("start-maximized")
if is_headless:
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('log-level=2')
driver = Chrome(options=chrome_options)
driver.implicitly_wait(10)
driver.get("https://facebook.com")
email = "email"
password = "pass"
login = "loginbutton"
approvals_code = "approvals_code"
emailelement = driver.find_element_by_name(email)
passwordelement = driver.find_element_by_name(password)
emailelement.send_keys(user_email_address)
passwordelement.send_keys(user_password)
loginelement = driver.find_element_by_id(login)
loginelement.click()
if "two-factor authentication" in driver.page_source.lower():
if two_factor_token:
twofactorelement = driver.find_element_by_name(approvals_code)
twofactorelement.send_keys(two_factor_token)
# Submits after the code is passed into the form, does not validate 2FA code.
contelement = driver.find_element_by_id("checkpointSubmitButton")
contelement.click()
# Defaults to saving this new browser, this occurs on each new automated login.
save_browser = driver.find_element_by_id("checkpointSubmitButton")
save_browser.click()
else:
# Allow time to enter 2FA code
print("Pausing to enter 2FA code")
time.sleep(20)
print("Continuing execution")
driver.get(user_profile_url)
return driver

41
deletefb/tools/wall.py

@ -0,0 +1,41 @@
import time
from selenium.webdriver.common.action_chains import ActionChains
from .common import SELENIUM_EXCEPTIONS
MAX_POSTS = 5000
def delete_posts(driver):
"""
Deletes or hides all posts from the wall
"""
for _ in range(MAX_POSTS):
post_button_sel = "_4xev"
while True:
try:
timeline_element = driver.find_element_by_class_name(post_button_sel)
actions = ActionChains(driver)
actions.move_to_element(timeline_element).click().perform()
menu = driver.find_element_by_css_selector("#globalContainer > div.uiContextualLayerPositioner.uiLayer > div")
actions.move_to_element(menu).perform()
try:
delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"FeedDeleteOption\"]")
except SELENIUM_EXCEPTIONS:
delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"HIDE_FROM_TIMELINE\"]")
actions.move_to_element(delete_button).click().perform()
confirmation_button = driver.find_element_by_class_name("layerConfirm")
# Facebook would not let me get focus on this button without some custom JS
driver.execute_script("arguments[0].click();", confirmation_button)
except SELENIUM_EXCEPTIONS:
continue
else:
break
# Required to sleep the thread for a bit after using JS to click this button
time.sleep(5)
driver.refresh()
Loading…
Cancel
Save