How to delete all your facebook photos with python




Introduction


As you mature, you think twice about expressing yourself. Nowadays most of our opinions, life experiences, and memories are shared online.  There are many photos on my Facebook profile that I don't resonate with anymore.

So I decided to write a Python script to purge them all. The code does browser automation using Selenium.

In the beginning, the bot logs in to a Facebook account. Then it starts to scroll through all the photos until it reaches the final one with the main purpose of collecting the URLs for later processing.

As for the next step, it opens each one of the photos in full width and clicks on the menu to find the Delete Photo button. Finally, it confirms the deletion.

Note: This tutorial doesn't teach you how to set up a python selenium scripting environment. 


Create the initial script


Once you have managed to open a fresh Python script, do the importing of the following utilities.


1
2
3
4
5
6
7
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC


import time


The following explains the reasons for including them in the script.

  • webdriver is required to launch the browser, like some type of engine behind automation.
  • WebDriverWait is used when locating elements from resources that take time to load.
  • By is used to write an expression for the location of different elements.
  • EC helps to check for the fulfillment of some type of condition, like waiting until the menu is clickable.

It's a good idea to disable Chrome notifications.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC


import time

# disable chrome notifications

chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_settings_values.notifications": 2}
chrome_options.add_experimental_option("prefs", prefs)


Define the web driver instance, pause time for scrolling, and also the WebDriverWait object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expted_conditions as EC


import time

# disable chrome notifications

chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_settings_values.notifications": 2}
chrome_options.add_experimental_option("prefs", prefs)


# instantiate webdriver interface

driver = webdriver.Chrome(chrome_options=chrome_options)


# define scroll pause time

scroll_pause_time = 0.5


# define wait


wait = WebDriverWait(driver, 5)

Log in to your Facebook account.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expted_conditions as EC


import time

# disable chrome notifications

chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_settings_values.notifications": 2}
chrome_options.add_experimental_option("prefs", prefs)


# instantiate webdriver interface

driver = webdriver.Chrome(chrome_options=chrome_options)


# define scroll pause time

scroll_pause_time = 0.5


# define wait


wait = WebDriverWait(driver, 5)


# login to facebook 

driver.get("http://www.facebook.com")


#target username

username = driver.find_element_by_id('email')
password = driver.find_element_by_id('pass')
 
# enter username and password

username.clear()
username.send_keys("youremail@some.com")
password.clear()


with open("credentials.txt", "r") as creds:
    for line in creds.readlines():
        plain_password = line
        break

password.send_keys(plain_password)

# target the login button and click it

login_button = driver.find_element_by_xpath("//button[text()='Log In']")
login_button.click()

time.sleep(5)



Define the following variables.

  • total_photos = 0, to keep count of photos that are deleted.
  • photo_page = your_photos_url_here, the url of your Facebook photo collection.
  • static_urls = [], URLs to be collected during scrolling. 
  • not_always_true = False, helps to control the termination of the while loop.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expted_conditions as EC


import time

# disable chrome notifications

chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_settings_values.notifications": 2}
chrome_options.add_experimental_option("prefs", prefs)


# instantiate webdriver interface

driver = webdriver.Chrome(chrome_options=chrome_options)


# define scroll pause time

scroll_pause_time = 0.5


# define wait


wait = WebDriverWait(driver, 5)


# login to facebook 

driver.get("http://www.facebook.com")


#target username

username = driver.find_element_by_id('email')
password = driver.find_element_by_id('pass')
 
# enter username and password

username.clear()
username.send_keys("youremail@some.com")
password.clear()


with open("credentials.txt", "r") as creds:
    for line in creds.readlines():
        plain_password = line
        break

password.send_keys(plain_password)

# target the login button and click it

login_button = driver.find_element_by_xpath("//button[text()='Log In']")
login_button.click()

time.sleep(5)

# define total photos deleted

total_photos = 0

# get photo page
photo_page = "your_photo_collection_url_here"

static_urls = []
 
not_always_true = False


Define the while loop inside the script


Selenium can also be used to scroll through a dynamic page. A while loop helps to go through the whole photo collection and for each one of them fetch the URL and store it inside the static_urls list.


The end of the dynamic page is calculated by an authentic string in the URL of the last photo. You must identify this yourself.


It is required to get the page first.


driver.get(photo_page)


The code with the while loop is shown below.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expted_conditions as EC


import time

# disable chrome notifications

chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_settings_values.notifications": 2}
chrome_options.add_experimental_option("prefs", prefs)


# instantiate webdriver interface

driver = webdriver.Chrome(chrome_options=chrome_options)


# define scroll pause time

scroll_pause_time = 0.5


# define wait


wait = WebDriverWait(driver, 5)


# login to facebook 

driver.get("http://www.facebook.com")


#target username

username = driver.find_element_by_id('email')
password = driver.find_element_by_id('pass')
 
# enter username and password

username.clear()
username.send_keys("youremail@some.com")
password.clear()


with open("credentials.txt", "r") as creds:
    for line in creds.readlines():
        plain_password = line
        break

password.send_keys(plain_password)

# target the login button and click it

login_button = driver.find_element_by_xpath("//button[text()='Log In']")
login_button.click()

time.sleep(5)

# define total photos deleted

total_photos = 0

# get photo page
photo_page = ""

static_urls = []
 
not_always_true = False


driver.get(photo_page)

while not not_always_true:
    time.sleep(scroll_pause_time)
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    anchors = driver.find_elements_by_tag_name("a")

    for a in anchors:
        try:
            url = a.get_attribute('href')
            if url is not None:
                if "photo.php?fbid=" in url and url not in static_urls:
                    static_urls.append(url)
                    if "1457511254507689" in url:
                        not_always_true = True
                        break
                else:
                    continue
        except:
            pass


Create the delete_photo function


Once the robot has managed to collect the whole URLs of the photos, it runs a for loop on the static_urls list with the only objective of deleting the resources.


Before creating the for loop, the delete_photo function should be defined. The code inside this function locates the following elements.

  • The menu of the photo.
  • The Delete Photo button.
  • The button for confirming the deletion of the photo.


It also uses the WebDriver instance to retrieve the photo in full width and height.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
menu_string = "//div[contains(@aria-label, 'Actions for this post') and @role='button']"


def delete_photo(photo_link):
    driver.get(photo_link)
    time.sleep(3)
    menu_button =  wait.until(EC.element_to_be_clickable((By.XPATH, menu_string))).click()

    time.sleep(2)


    # Find the button using text

    el = driver.find_elements_by_xpath \
            ("//*[contains(text(), 'Delete Photo')]")

    el = el[0]

    el.click()

    time.sleep(0.3)


    confirm_del = driver.find_elements_by_css_selector \
        ("[aria-label=Delete]")  

    confirm_del[1].click()

    time.sleep(1.7)


As you can see the time module is being used inside the above function. It helps to freeze the time so the resources are fully loaded for the script to process them.


Now the script is almost done.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expted_conditions as EC


import time

# disable chrome notifications

chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_settings_values.notifications": 2}
chrome_options.add_experimental_option("prefs", prefs)


# instantiate webdriver interface

driver = webdriver.Chrome(chrome_options=chrome_options)


# define scroll pause time

scroll_pause_time = 0.5


# define wait


wait = WebDriverWait(driver, 5)


# login to facebook 

driver.get("http://www.facebook.com")


#target username

username = driver.find_element_by_id('email')
password = driver.find_element_by_id('pass')
 
# enter username and password

username.clear()
username.send_keys("youremail@some.com")
password.clear()


with open("credentials.txt", "r") as creds:
    for line in creds.readlines():
        plain_password = line
        break

password.send_keys(plain_password)

# target the login button and click it

login_button = driver.find_element_by_xpath("//button[text()='Log In']")
login_button.click()

time.sleep(5)

# define total photos deleted

total_photos = 0

# get photo page
photo_page = ""

static_urls = []
 
not_always_true = False


driver.get(photo_page)

while not not_always_true:
    time.sleep(scroll_pause_time)
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    anchors = driver.find_elements_by_tag_name("a")

    for a in anchors:
        try:
            url = a.get_attribute('href')
            if url is not None:
                if "photo.php?fbid=" in url and url not in static_urls:
                    static_urls.append(url)
                    if "1457511254507689" in url:
                        not_always_true = True
                        break
                else:
                    continue
        except:
            pass


menu_string = "//div[contains(@aria-label, 'Actions for this post') and @role='button']"


def delete_photo(photo_link):
    driver.get(photo_link)
    time.sleep(3)
    menu_button =  wait.until(EC.element_to_be_clickable((By.XPATH, menu_string))).click()

    time.sleep(2)


    # Find the button using text

    el = driver.find_elements_by_xpath \
            ("//*[contains(text(), 'Delete Photo')]")

    el = el[0]

    el.click()

    time.sleep(0.3)


    confirm_del = driver.find_elements_by_css_selector \
        ("[aria-label=Delete]")  

    confirm_del[1].click()

    time.sleep(1.7)


Add the for loop to start deleting photos in bulk


After the script has finished collecting URLs of the photos, the next step is to run a for loop through them and execute the delete_photo function.


1
2
3
4
5
for photo in static_urls:
    delete_photo(photo)
    total_photos += 1

    print("Total photos deleted: %d" % total_photos)


The final script


Although there may be minor differences in your code when compared to mine, you should end up with something similar to the script shown below.



  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expted_conditions as EC


import time

# disable chrome notifications

chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_settings_values.notifications": 2}
chrome_options.add_experimental_option("prefs", prefs)


# instantiate webdriver interface

driver = webdriver.Chrome(chrome_options=chrome_options)


# define scroll pause time

scroll_pause_time = 0.5


# define wait


wait = WebDriverWait(driver, 5)


# login to facebook 

driver.get("http://www.facebook.com")


#target username

username = driver.find_element_by_id('email')
password = driver.find_element_by_id('pass')
 
# enter username and password

username.clear()
username.send_keys("youremail@some.com")
password.clear()


with open("credentials.txt", "r") as creds:
    for line in creds.readlines():
        plain_password = line
        break

password.send_keys(plain_password)

# target the login button and click it

login_button = driver.find_element_by_xpath("//button[text()='Log In']")
login_button.click()

time.sleep(5)

# define total photos deleted

total_photos = 0

# get photo page
photo_page = ""

static_urls = []
 
not_always_true = False


driver.get(photo_page)

while not not_always_true:
    time.sleep(scroll_pause_time)
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    anchors = driver.find_elements_by_tag_name("a")

    for a in anchors:
        try:
            url = a.get_attribute('href')
            if url is not None:
                if "photo.php?fbid=" in url and url not in static_urls:
                    static_urls.append(url)
                    if "1457511254507689" in url:
                        not_always_true = True
                        break
                else:
                    continue
        except:
            pass


menu_string = "//div[contains(@aria-label, 'Actions for this post') and @role='button']"


def delete_photo(photo_link):
    driver.get(photo_link)
    time.sleep(3)
    menu_button =  wait.until(EC.element_to_be_clickable((By.XPATH, menu_string))).click()

    time.sleep(2)


    # Find the button using text

    el = driver.find_elements_by_xpath \
            ("//*[contains(text(), 'Delete Photo')]")

    el = el[0]

    el.click()

    time.sleep(0.3)


    confirm_del = driver.find_elements_by_css_selector \
        ("[aria-label=Delete]")  

    confirm_del[1].click()

    time.sleep(1.7)


for photo in static_urls:
    delete_photo(photo)
    total_photos += 1

    print("Total photos deleted: %d" % total_photos)


Script in action


To run the script, activate your virtual environment and type:

python fbdeletephoto.py

Note: Make sure to put the name of your script above.



Script deleting Facebook photos




The script running smooth and continuing the deletion process


Facebook detected the script after 249 photos were deleted



Final thoughts


Automation is very helpful when you have to process a lot of data. The script performs without interruption until Facebook detects it as a robot.  

As soon as Facebook removes the temporary block, you can run the script again and let it purge photos while you enjoy some type of drink.


© 2022 Copyright by orthodoxpirate.blogspot.com
All Rights Reserved
Share on Google Plus

About Oltjano Backa

Always curious on how stuff works under the hood, hacking has always been my way of materializing the true essence of my soul in the third dimension. My life as a hacker got really interesting when I discovered Python and Ubuntu Linux. Thirsty for knowledge, open-source technologies are my main toys.

0 Comments:

Post a Comment