Skip to content

Commit 1761dbf

Browse files
committed
Initial release
Full initial release with all necessary files.
1 parent 34a04dd commit 1761dbf

File tree

6 files changed

+772
-2
lines changed

6 files changed

+772
-2
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
chrome_profile/
2+
logs/
3+
__pycache__/

README.md

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,64 @@
1-
# InstaWipe
2-
Automates deleting all posts on Instagram
1+
# InstaWipe 🧹
2+
3+
[![Python](https://img.shields.io/badge/Python-3776AB?logo=python&logoColor=fff)](#) [![Selenium](https://img.shields.io/badge/Selenium-43B02A?logo=selenium&logoColor=fff)](#) [![Instagram](https://img.shields.io/badge/Instagram-%23E4405F.svg?logo=Instagram&logoColor=white)](#) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4+
5+
#### ⚠️ Two-Factor Authentication must be disabled before use!
6+
7+
## 🌐 Overview
8+
9+
InstaWipe is an automation tool for the deletion of Instagram posts. Built for simplicity and reliability, it navigates Instagram, locates your posts, and deletes them efficiently all while not getting caught by Instagram's anti-bot detection.
10+
11+
## 🚀 Features
12+
13+
- Anti-bot Measure Avoidance
14+
- Automated Post Deletion
15+
- Customizable
16+
- Popup Handling
17+
- Robust Error Handling
18+
19+
## 🔧 Prerequisites
20+
21+
- [Chrome Browser](https://www.google.com/chrome/)
22+
23+
- [Git](https://git-scm.com/downloads)
24+
25+
- [Python](https://www.python.org/downloads/)
26+
27+
- Python packages (instructions in Installation section)
28+
29+
## 🛠️ Installation
30+
31+
1. Clone the repository
32+
33+
```bash
34+
git clone https://github.com/ajwdd/InstaWipe.git
35+
```
36+
37+
2. Install the Python packages
38+
39+
```bash
40+
cd InstaWipe
41+
pip3 install -r requirements.txt
42+
```
43+
44+
## 📖 Usage
45+
46+
1. Run the script
47+
48+
```bash
49+
python3 app.py
50+
```
51+
52+
2. Enter your Instagram credentials when prompted
53+
54+
```bash
55+
Enter your Instagram username:
56+
57+
Enter your Instagram password:
58+
```
59+
60+
**Note:** Password will not show when typing it.
61+
62+
3. Done, let it do it's thing. You may minimize the browser.
63+
64+
**Note:** Ensure your computer won't sleep.

app.py

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
import logging as log
2+
import time
3+
from getpass import getpass
4+
from selenium.webdriver.support.ui import WebDriverWait
5+
from selenium.webdriver.support import expected_conditions as EC
6+
from selenium.webdriver.common.by import By
7+
from selenium.common.exceptions import NoSuchWindowException, TimeoutException
8+
from termcolor import colored
9+
from base import (
10+
clear_cmd,
11+
site_login,
12+
get_driver,
13+
close_shop,
14+
click_element,
15+
random_time,
16+
get_length_of_page,
17+
start_end_log,
18+
check_session,
19+
)
20+
from config import Settings
21+
22+
23+
def delete_post(driver):
24+
"""
25+
Delete a post from the user's profile.
26+
This function finds and clicks the more options, delete, and delete confirmation button.
27+
28+
Args:
29+
driver: The Selenium WebDriver instance.
30+
Returns:
31+
bool: True if the post was deleted successfully, False otherwise.
32+
"""
33+
try:
34+
# Wait for load and find the three-dot menu (more options)
35+
wait = WebDriverWait(driver, 15)
36+
menu_btn = wait.until(
37+
EC.element_to_be_clickable(
38+
(By.CSS_SELECTOR, "svg[aria-label='More options']")
39+
)
40+
)
41+
if not menu_btn:
42+
log.info("Options button not found.\nSkipping post...")
43+
return False
44+
click_element(driver, menu_btn, "More options")
45+
random_time()
46+
47+
# Click delete option
48+
delete_btn = wait.until(
49+
EC.element_to_be_clickable(
50+
(By.CSS_SELECTOR, "button:not([disabled])[tabindex='0']")
51+
)
52+
)
53+
if not delete_btn or "Delete" not in delete_btn.text:
54+
log.info("Delete button not found.\nSkipping post...")
55+
return False
56+
click_element(driver, delete_btn, "Delete")
57+
random_time()
58+
59+
# Click confirm deletion option
60+
confirm_btn = wait.until(
61+
EC.element_to_be_clickable(
62+
(By.CSS_SELECTOR, "button:not([disabled])[tabindex='0']")
63+
)
64+
)
65+
if not confirm_btn or "Delete" not in confirm_btn.text:
66+
log.info("Confirm delete button not found or incorrect.")
67+
return False
68+
click_element(driver, confirm_btn, "Confirm Delete")
69+
random_time()
70+
log.info("Post deleted successfully.")
71+
return True
72+
except Exception as ex:
73+
log.error(f"Error deleting post: {ex}", exc_info=True)
74+
return False
75+
76+
77+
def main():
78+
start_end_log(__file__)
79+
driver = None
80+
username = None
81+
password = None
82+
posts_deleted = 0
83+
settings = Settings()
84+
max_posts = settings.max_posts
85+
max_scrolls = settings.max_scrolls
86+
try:
87+
clear_cmd()
88+
# ASCII art banner
89+
banner = colored(
90+
"""
91+
___ _ __ ___
92+
|_ _|_ __ ___| |_ __ \\ \\ / (_)_ __ ___
93+
| || '_ \\/ __| __/ _` \\ \\ /\\ / /| | '_ \\ / _ \\
94+
| || | | \\__ \\ || (_| |\\ V V / | | |_) | __/
95+
|___|_| |_|___/\\__\\__,_| \\_/\\_/ |_| .__/ \\___|
96+
|_|
97+
https://github.com/ajwdd
98+
""",
99+
color="magenta",
100+
attrs=["bold"],
101+
)
102+
print(banner)
103+
104+
# Get user's Instagram credentials
105+
print("Enter your Instagram credentials.")
106+
username = input("Username: ").strip().lower()
107+
password = getpass("Password: ").strip()
108+
if not username or not password:
109+
warning = colored(
110+
"Username or password cannot be empty!", color="red", attrs=["blink"]
111+
)
112+
print(warning)
113+
input("Press any key to retry...")
114+
main()
115+
116+
driver = get_driver()
117+
driver = site_login(driver, username, password)
118+
119+
# Navigate to profile and wait for load
120+
driver.get(f"https://www.instagram.com/{username}/")
121+
wait = WebDriverWait(driver, 20)
122+
wait.until(
123+
EC.presence_of_element_located(
124+
(By.XPATH, f"//a[contains(@href, '/{username}/p/')]")
125+
)
126+
)
127+
random_time()
128+
129+
while posts_deleted < max_posts:
130+
# Check session validity
131+
if not check_session(driver):
132+
log.info("Session invalid, restarting driver")
133+
close_shop(driver)
134+
driver = get_driver()
135+
driver = site_login(driver, username, password)
136+
driver.get(f"https://www.instagram.com/{username}/")
137+
wait.until(
138+
EC.presence_of_element_located(
139+
(By.XPATH, f"//a[contains(@href, '/{username}/p/')]")
140+
)
141+
)
142+
random_time()
143+
144+
# Scroll multiple times to load posts
145+
last_height = get_length_of_page(driver)
146+
for _ in range(max_scrolls):
147+
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
148+
time.sleep(2)
149+
new_height = get_length_of_page(driver)
150+
if new_height == last_height:
151+
log.info("No new posts loaded after scrolling.")
152+
break
153+
last_height = new_height
154+
155+
# Wait for post links to load (with retry)
156+
posts = []
157+
for attempt in range(2):
158+
try:
159+
wait = WebDriverWait(driver, 20)
160+
posts = wait.until(
161+
EC.presence_of_all_elements_located(
162+
(By.XPATH, f"//a[contains(@href, '/{username}/p/')]")
163+
)
164+
)
165+
break
166+
except Exception as ex:
167+
log.warning(
168+
f"Attempt {attempt + 1}: No posts found, retrying... {ex}"
169+
)
170+
time.sleep(5)
171+
log.info(f"Found {len(posts)} posts")
172+
173+
if not posts:
174+
log.info("No more posts found")
175+
break
176+
177+
# Process the first available post
178+
try:
179+
post = posts[0]
180+
click_element(driver, post, "Post")
181+
random_time()
182+
if delete_post(driver):
183+
posts_deleted += 1
184+
except Exception as ex:
185+
log.error(f"Error processing post: {ex}", exc_info=True)
186+
187+
# Navigate back and wait for profile to reload
188+
driver.get(f"https://www.instagram.com/{username}/")
189+
try:
190+
wait.until(
191+
EC.presence_of_element_located(
192+
(By.XPATH, f"//a[contains(@href, '/{username}/p/')]")
193+
)
194+
)
195+
except TimeoutException:
196+
log.info("No posts found after navigation.\nExiting...")
197+
break
198+
random_time()
199+
200+
log.info(f"Deleted {posts_deleted} posts")
201+
202+
except NoSuchWindowException as ex:
203+
log.error(f"Browser window closed unexpectedly:\n{ex}", exc_info=True)
204+
except Exception as ex:
205+
log.error(f"Error in main:\n{ex}", exc_info=True)
206+
finally:
207+
if driver:
208+
close_shop(driver)
209+
start_end_log(__file__, end_log=True)
210+
211+
212+
if __name__ == "__main__":
213+
main()

0 commit comments

Comments
 (0)