-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.py
123 lines (110 loc) · 8.46 KB
/
main.py
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
"""
Created by: https://github.com/ibnaleem
Contribute: https://github.com/ibnaleem/instatracker
"""
from rich.console import Console
from argparse import ArgumentParser
import datetime, instaloader, os, time
from instaloader.exceptions import AbortDownloadException
ascii_art = """
___ _ _____ _
|_ _|_ __ ___| |_ __ |_ _| __ __ _ ___| | _____ _ __
| || '_ \/ __| __/ _` || || '__/ _` |/ __| |/ / _ \ '__|
| || | | \__ \ || (_| || || | | (_| | (__| < __/ |
|___|_| |_|___/\__\__,_||_||_| \__,_|\___|_|\_\___|_|
"""
class InstaTracker:
def __init__(self, username: str):
self.username: str = username
self.instaloader = instaloader
self.bot = self.instaloader.Instaloader()
self.console = Console()
@property
def date(self):
return datetime.datetime.now(datetime.UTC)
def get_followers(self):
profile = self.instaloader.Profile.from_username(self.bot.context, self.username)
return profile.followers
def get_following(self):
profile = self.instaloader.Profile.from_username(self.bot.context, self.username)
return profile.followees
def get_posts(self):
profile = self.instaloader.Profile.from_username(self.bot.context, self.username)
return profile.mediacount
def get_bio(self):
profile = self.instaloader.Profile.from_username(self.bot.context, self.username)
return profile.biography
def write_to_file(self, data):
with open(f"{self.username}_logs.txt", "a") as f:
f.write(f"{data}\n")
def main(self):
os.system("clear" if not os.name == "nt" else "cls")
self.console.print(ascii_art, style="bold blue")
print("Logging in...")
# You must manually login to avoid any login errors. Below, replace the fields 'user'
# and 'passwd' with your username and password. If you'd like, you can create a brand
# new Instagram only for this script. Usernames and passwords are never logged.
# If this script is throwing BadCredentials exception, use a different Instagram account.
self.bot.login(user="YOUR INSTAGRAM USERNAME", passwd="YOUR INSTAGRAM PASSWORD") # this allows us to access & scrape Instagram.
self.console.print(f"[bold green]Welcome to InstaTracker[/bold green]")
self.console.print(f"[bold blue]Getting initial data for {self.username}...[/bold blue]")
initial = {"followers": self.get_followers(), "following": self.get_following(), "posts": self.get_posts(), "bio": self.get_bio()}
self.write_to_file(f"------{self.date}------\n{self.username} has {initial["followers"]}\n{self.username} is following {initial["following"]} people\n{self.username} has {initial["posts"]} posts\n{self.username} has the following bio: {initial["bio"]}")
self.console.print(f"[bold blue]------{self.date}------[/bold blue]")
self.console.print(f"[bold blue]{self.username} has {self.get_followers()} followers[/bold blue]")
self.console.print(f"[bold blue]{self.username} is following {self.get_following()} people[/bold blue]")
self.console.print(f"[bold blue]{self.username} has {self.get_posts()} posts[/bold blue]")
self.console.print(f"[bold blue]{self.username} has the following bio: {self.get_bio()}[/bold blue]")
self.console.print(f"[bold green]Tracking started! I will log all changes to {self.username}_logs.txt and this terminal![/bold green]")
while True:
time.sleep(300)
if self.get_followers() != initial["followers"]:
if initial["followers"] > self.get_followers():
self.console.print(f"[bold red]------{self.date}------[/bold red]")
self.console.print(f"[bold red]{self.username} has lost {initial['followers'] - self.get_followers()} followers ({initial['followers']} followers --> {self.get_followers()} followers)[/bold red]")
self.write_to_file(f"------{self.date}------\n{self.username} has lost {initial['followers'] - self.get_followers()} followers ({initial['followers']} followers --> {self.get_followers()} followers)")
else:
self.console.print(f"[bold red]------{self.date}------[/bold red]")
self.console.print(f"[bold green]{self.username} has gained {self.get_followers() - initial['followers']} followers ({initial['followers']} followers --> {self.get_followers()} followers)[/bold green]")
self.write_to_file(f"------{self.date}------\n{self.username} has gained {self.get_followers() - initial['followers']} followers ({initial['followers']} followers --> {self.get_followers()} followers)")
initial["followers"] = self.get_followers()
if self.get_following() != initial["following"]:
if initial["following"] > self.get_following():
self.console.print(f"[bold red]------{self.date}------[/bold red]")
self.console.print(f"[bold red]{self.username} has unfollowed {initial['following'] - self.get_following()} people ({initial['following']} following --> {self.get_following()} following)[/bold red]")
self.write_to_file(f"------{self.date}------\n{self.username} has unfollowed {initial['following'] - self.get_following()} people ({initial['following']} following --> {self.get_following()} following)")
else:
self.console.print(f"[bold red]------{self.date}------[/bold red]")
self.console.print(f"[bold green]{self.username} has followed {self.get_following() - initial['following']} people ({initial['following']} following --> {self.get_following()} following)[/bold green]")
self.write_to_file(f"------{self.date}------\n{self.username} has followed {self.get_following() - initial['following']} people ({initial['following']} following --> {self.get_following()} following)")
initial["following"] = self.get_following()
if self.get_posts() != initial["posts"]:
if initial["posts"] > self.get_posts():
self.console.print(f"[bold red]------{self.date}------[/bold red]")
self.console.print(f"[bold red]{self.username} has deleted {initial['posts'] - self.get_posts()} posts ({initial['posts']} posts --> {self.get_posts()} posts)[/bold red]")
self.write_to_file(f"------{self.date}------\n{self.username} has deleted {initial['posts'] - self.get_posts()} posts ({initial['posts']} posts --> {self.get_posts()} posts)")
else:
self.console.print(f"[bold red]------{self.date}------[/bold red]")
self.console.print(f"[bold green]{self.username} has posted {self.get_posts() - initial['posts']} posts ({initial['posts']} posts --> {self.get_posts()} posts)[/bold green]")
self.write_to_file(f"------{self.date}------\n{self.username} has posted {self.get_posts() - initial['posts']} posts ({initial['posts']} posts --> {self.get_posts()} posts)")
initial["posts"] = self.get_posts()
if self.get_bio() != initial["bio"]:
self.console.print(f"[bold red]------{self.date}------[/bold red]")
self.console.print(f"[bold green]{self.username} has updated their bio:[/bold green]")
self.console.print(f"[bold red] Before: {initial['bio']}[/bold red]")
self.console.print(f"[bold green] After: {self.get_bio()}[/bold green]")
self.write_to_file(f"------{self.date}------\n{self.username} has updated their bio:\nBefore: {initial['bio']}\nAfter: {self.get_bio()}")
initial["bio"] = self.get_bio()
if __name__ == "__main__":
parser = ArgumentParser(prog="Instagram Tracker",
description="📸 an Instagram tracker that logs any changes to an Instagram account (followers, following, posts, and bio)",
epilog="🤝 Contribute: https://github.com/ibnaleem/instatracker")
parser.add_argument("-u", "--username", help="The username of the account to track", required=True)
args = parser.parse_args()
tracker = InstaTracker(str(args.username))
try:
tracker.main()
except Exception:
tracker.console.print(f"[bold red]------{tracker.date}------\nLogged out of Instagram... Logging in again....[/bold red]")
tracker.write_to_file(f"------{tracker.date}------\nLogged out of Instagram... Logging in again....")
tracker.main()