FacebookCleanup
An automated, local toolkit to audit, review, and selectively clean up your Facebook friends list while preserving full control, decision history, and account safety.
Built with Python, Flask, Playwright, and SQLite.
Table of Contents
- Overview & Workflow Order
- Project Prerequisites & Setup
- Scripts Reference & Order of Use
- Database Architecture & Data Safety
- Facebook Anti-Abuse, Rate Limits & Best Practices
- Troubleshooting & FAQ
Overview & Workflow Order
The cleanup process follows a sequential 5-phase lifecycle:
flowchart LR
A["1. Login / 2FA\n(test_facebook.py)"] --> B["2. Ingest Friends\n(collect_friends.py)"]
B --> C["3. Cache Photos\n(collect_photos.py)"]
C --> D["4. Review & Decide\n(app.py on :8765)"]
D --> E["5. Execute Removal\n(cleanup_runner.py)"]
- Authenticate: Establish and persist a valid Facebook session in the local Playwright profile (
browser_profile/). - Collect: Ingest visible friends from your Facebook friends list into SQLite.
- Enrich: Cache thumbnail profile pictures so you can visually identify friends during review.
- Review: Launch the local Flask app at
http://127.0.0.1:8765to review each person one-by-one (KEEP / REMOVE / UNDO), with automatic background discovery of mutual friends. - Clean: Execute removals safely in controlled batches (3-in-1: Unfollow, Delete Chat, Unfriend).
Project Prerequisites & Setup
Environment Requirements
- OS: Windows, macOS, or Linux
- Python: 3.10+
- Virtual Environment:
.venvin your project directory
Installation & Setup Options
Option A: Install via pip from GitHub (Quickest)
pip install git+https://github.com/ticonetster/fb-friend-cleanup.git
playwright install chromium
Once installed, you can launch the tools from any directory:
fb-cleanup-app- Starts the local web review interface athttp://127.0.0.1:8765fb-cleanup-runner- Starts the automated 3-in-1 cleanup batch execution
Option B: Download Release Package (.whl)
Download fb_friend_cleanup-1.0.0-py3-none-any.whl from the Latest GitHub Release and install:
pip install fb_friend_cleanup-1.0.0-py3-none-any.whl
playwright install chromium
Option C: Clone and Run from Source (Recommended for Local Customization)
# Clone the repository (or open your existing project folder)
git clone https://github.com/ticonetster/fb-friend-cleanup.git
cd fb-friend-cleanup
# Create and activate virtual environment
# Windows (PowerShell):
python -m venv .venv
.\.venv\Scripts\Activate.ps1
# macOS / Linux:
python3 -m venv .venv
source .venv/bin/activate
# Install package dependencies
pip install -e .
# Install Chromium browser binaries for Playwright
playwright install chromium
Scripts Reference & Order of Use
Step 1: Session Authentication (test_facebook.py)
- Purpose: Opens a visible Chromium window using the dedicated persistent profile folder (
browser_profile/). Used to log in, solve 2FA prompts, and click "Remember browser". - When to run:
- Initial project setup.
- Whenever Facebook logs you out or prompts for 2FA.
- Usage:
python test_facebook.py - Instructions:
- The browser will open to
https://www.facebook.com/. - Enter your email and password, complete any 2FA challenge, and select "Save Browser / Remember Browser".
- Once on your Facebook feed, return to the terminal and press Enter to save the session and close the browser.
- The browser will open to
Step 2: Collect Friends (collect_friends.py)
- Purpose: Navigates to
https://www.facebook.com/me/friends, reads visible friend cards, normalizes profile URLs, and seeds thefriendstable infriends.sqlite3withdecision='pending'. - When to run: After logging in, to ingest your full Facebook friends list.
- Usage:
python collect_friends.py - Instructions:
- A browser window opens directly to your Facebook friends page.
- Manually scroll down through your friends list until all or most friends have loaded into the DOM.
- Return to the terminal and press Enter.
- The script filters system links, normalizes profile URLs to
https://www.facebook.com/<username>, and inserts new records usingINSERT OR IGNORE.
Step 3: Collect Profile Photos (collect_photos.py)
- Purpose: Captures thumbnail avatar URLs from the friends list page and populates the
photo_urlcolumn infriends.sqlite3. - When to run: Immediately after collecting friends, before starting review.
- Usage:
python collect_photos.py - Instructions:
- The browser opens your friends list.
- Scroll through the page so friend thumbnail images are visibly rendered.
- Press Enter in the terminal.
- The script updates matching records in
friendswith their high-resolution or thumbnail CDN photo URL.
Step 4: Interactive Review Web App (app.py)
- Purpose: Local web interface to review each candidate profile individually, make KEEP/REMOVE decisions, undo mistakes, and view mutual friends.
- Features:
- Zero Destructive Actions: Only updates local review decisions (
keep/remove). Does not modify Facebook relationships. - Automatic Mutual-Friend Discovery: Runs in a non-blocking background worker thread using the authenticated browser session. Distinguishes between:
- Found: Lists mutual friends with avatars, names, and direct profile links.
- None: Confirmed zero mutual friends.
- Unavailable: Private / restricted friends list.
- Error: Network or session error with an in-UI "Retry" button.
- Asynchronous UI: KEEP and REMOVE buttons remain responsive instantly without waiting for mutual-friend lookups.
- Undo Support: Reverts previous decisions seamlessly.
- Zero Destructive Actions: Only updates local review decisions (
- Usage:
python app.py # Or run the installed CLI command: fb-cleanup-app
- Accessing the App:
- Open
http://127.0.0.1:8765in your browser. - Review candidates until all profiles reach 100% completion.
- Open
Step 5: 3-in-1 Cleanup Execution (cleanup_runner.py)
- Purpose: Automates the removal of profiles marked with
decision='remove'infriends.sqlite3. - For each candidate, it performs 3 sequential actions:
- Unfollow: Accesses profile options to unfollow, immediately clearing their posts from your Facebook feed.
- Delete Chat: Opens Messenger, accesses chat settings, and deletes the conversation history (or marks
no_chatif no messages exist). - Unfriend: Clicks the "Friends" menu, selects "Unfriend", and confirms the removal modal.
Safety Controls & Anti-Abuse Features
- Batched Execution: Configurable batch size (default: 30 profiles per run).
- Human Pacing & Jitter: Randomized delays between 10 and 22 seconds per profile, plus 30–45s micro-cooldowns every 10 actions.
- Automated Checkpoint Detection: Immediately halts if Facebook displays "Please slow down", "You're temporarily blocked", action blocks, or CAPTCHAs.
- Persistent State Tracking: Every operation is logged in the
removal_logtable with timestamps, individual step statuses (unfollow_status,chat_status,unfriend_status), and error messages. - Resumable: If stopped or interrupted, re-running the script picks up exactly where it left off.
Commands & Flags
| Command | Purpose |
|---|---|
python cleanup_runner.py --single --dry-run |
Dry Run: Inspects 1 profile, checks buttons without clicking final confirm. |
python cleanup_runner.py --single |
Live Single Test: Performs live Unfollow, Chat deletion, and Unfriend on 1 profile. |
python cleanup_runner.py |
Standard Batch: Processes the next batch of 30 queued profiles with pacing. |
python cleanup_runner.py --batch-size 15 |
Processes a smaller batch of 15 profiles. |
python cleanup_runner.py --delay-min 15 --delay-max 30 |
Increases delays between actions for extra caution. |
python cleanup_runner.py --headless |
Runs browser in background headless mode (default is headed window). |
Database Architecture & Data Safety
All application data is maintained in SQLite at friends.sqlite3:
erDiagram
friends ||--o| mutual_friend_cache : "caches mutuals for"
friends ||--o{ mutual_friends : "contains"
friends ||--o| removal_log : "tracked in"
friends {
text profile_url PK
text name
text decision "pending | keep | remove"
text photo_url
text reviewed_at
}
mutual_friend_cache {
text profile_url PK
text status "found | none | unavailable | error"
text error_message
int friend_count
text fetched_at
}
mutual_friends {
int id PK
text target_profile_url
text mutual_profile_url
text name
text photo_url
text created_at
}
removal_log {
text profile_url PK
text name
text status "pending | removed | failed | skipped"
text unfollow_status
text chat_status
text unfriend_status
int attempts
text last_error
text removed_at
text created_at
}
Backups and Exports
friends_backup_*.sqlite3: Full point-in-time SQLite backups.to_remove.csv: Exported CSV list of all profiles marked for removal.to_keep.csv: Exported CSV list of all profiles marked to keep.
Facebook Anti-Abuse, Rate Limits & Best Practices
Facebook aggressively monitors account relationship changes. Adhere to these guidelines to keep your account safe:
- Avoid Bulk Rushing: Do not attempt to remove hundreds of friends in a single hour.
- Pacing Recommendation:
- Limit to 1–2 batches of 30 profiles per day (or 30–60 removals daily).
- Allow natural gaps (several hours) between batches.
- If an Action Block Appears:
- If Facebook shows "You're temporarily blocked from using this feature", stop immediately.
- Do not test or attempt manual unfriends during a block.
- Wait 24 full hours for the automated rate limit to expire completely before resuming.
Troubleshooting & FAQ
Browser redirects to 2FA / "Remember Browser" on startup
- Symptom:
cleanup_runner.pypauses or prompts for login. - Resolution: A visible browser window will open. Click "Save Browser" or "Don't Save" on the Facebook prompt, then press Enter in your terminal to proceed.
An individual profile fails with a timeout
- Facebook occasionally delays background media loading on certain heavy profiles.
cleanup_runner.pycatches these timeouts, logs the issue toremoval_logwith status'failed', and continues with the rest of the batch.- To retry failed profiles at any time, run:
python -c "import cleanup_runner; db = cleanup_runner.connect(); db.execute('UPDATE removal_log SET status=\"pending\" WHERE status=\"failed\"'); db.commit(); print('Failed profiles reset to pending.')"
How do I check current progress?
Run this one-liner to view remaining and completed counts:
python -c "import cleanup_runner; print(cleanup_runner.get_removal_stats())"
License
This project is licensed under the GNU General Public License v3.0 (GPLv3) - see the LICENSE file for full details.
Disclaimer
This software is provided for personal data management and curation purposes. It is not affiliated with, authorized, maintained, or endorsed by Meta Platforms, Inc. Use responsibly and adhere to platform rate limits.
Metadata
Release files for fb-friend-cleanup 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fb_friend_cleanup-1.0.0.tar.gz | 37.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fb_friend_cleanup-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 73.8 kB
Release files / fb_friend_cleanup-1.0.0.tar.gz
| Download URL | fb_friend_cleanup-1.0.0.tar.gz |
|---|---|
| Size | 37.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0885cff320b8de0700d0c66af45db3c0463a77915b4c2d815d8d5c128f189184
|
|
BLAKE2b-256 checksum How to use checksums |
d2ef3b08418a340f6aeb833cbbbdf813510ca6c3c43c74e107eb83a6b164d580
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Release files / fb_friend_cleanup-1.0.0-py3-none-any.whl
| Download URL | fb_friend_cleanup-1.0.0-py3-none-any.whl |
|---|---|
| Size | 35.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
92462a4c8e6af54ebbedae958a0165a5d3b25bf6852a2fb145db1a20464bf77a
|
|
BLAKE2b-256 checksum How to use checksums |
705ae93d5169aa5ca9e6cb5e744427802959597d9906697824411b66069314c4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|