|
| 1 | +from selenium import webdriver |
| 2 | +import pathlib |
| 3 | +from time import sleep |
| 4 | +from cryptography.fernet import Fernet |
| 5 | +from selenium.webdriver.common.by import By |
| 6 | +from selenium.webdriver.support.ui import WebDriverWait |
| 7 | +from selenium.webdriver.support import expected_conditions as EC |
| 8 | + |
| 9 | + |
| 10 | +class InstaBot: |
| 11 | + def __init__(self, username, pw): |
| 12 | + path=pathlib.Path().absolute() |
| 13 | + try: |
| 14 | + self.driver = webdriver.Chrome(r"{}\{}".format(path,"chromedriver.exe")) |
| 15 | + except: |
| 16 | + try: |
| 17 | + self.driver = webdriver.Firefox(r"{}\{}".format(path,"geckodriver.exe")) |
| 18 | + except: |
| 19 | + try: |
| 20 | + self.driver = webdriver.Opera(r"{}\{}".format(path,"operadriver.exe")) |
| 21 | + except: |
| 22 | + print("Webdriver not found") |
| 23 | + |
| 24 | + print("\n----Please wait for the menu, as we are signing in through your id----") |
| 25 | + self.driver.get("https://instagram.com") |
| 26 | + self.wait = WebDriverWait(self.driver, 10).until |
| 27 | + |
| 28 | + self.wait(EC.presence_of_element_located((By.XPATH, "//input[@name='username']"))) \ |
| 29 | + .send_keys(username) |
| 30 | + self.driver.find_element_by_xpath("//input[@name='password']") \ |
| 31 | + .send_keys(pw) |
| 32 | + self.driver.find_element_by_xpath('//button[@type="submit"]') \ |
| 33 | + .click() |
| 34 | + try: |
| 35 | + self.driver.find_element_by_xpath("//input[@aria-label='Security Code']") |
| 36 | + print("\nEnter the otp and login to continue\n") |
| 37 | + for _ in range(2): |
| 38 | + WebDriverWait(self.driver, 50).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(., 'Not Now')]"))) \ |
| 39 | + .click() |
| 40 | + self.driver.minimize_window() |
| 41 | + except: |
| 42 | + for _ in range(2): |
| 43 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//button[contains(., 'Not Now')]"))) \ |
| 44 | + .click() |
| 45 | + self.driver.minimize_window() |
| 46 | + |
| 47 | + def get_unfollowers(self): |
| 48 | + self.driver.find_element_by_xpath("//img[@alt='Instagram']") \ |
| 49 | + .click() |
| 50 | + self.driver.maximize_window() |
| 51 | + self.wait(EC.element_to_be_clickable((By.CSS_SELECTOR, " div:nth-child(5) > span > img"))) \ |
| 52 | + .click() |
| 53 | + self.driver.find_element_by_xpath("//div[text()='Profile']").click() |
| 54 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//a[contains(@href,'/following')]"))) \ |
| 55 | + .click() |
| 56 | + following = self._get_names() |
| 57 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//a[contains(@href,'/followers')]"))) \ |
| 58 | + .click() |
| 59 | + followers = self._get_names() |
| 60 | + not_following_back = [user for user in following if user not in followers] |
| 61 | + you_not_following_back = [user for user in followers if user not in following] |
| 62 | + self.driver.find_element_by_xpath("//img[@alt='Instagram']") \ |
| 63 | + .click() |
| 64 | + |
| 65 | + with open("Not Following Back", "w") as f1: |
| 66 | + f1.write("\n".join(not_following_back)) |
| 67 | + |
| 68 | + with open("You not Following Back", "w") as f2: |
| 69 | + f2.write("\n".join(you_not_following_back)) |
| 70 | + self.driver.minimize_window() |
| 71 | + |
| 72 | + print("People who aren't following back ({}) :\n".format(len(not_following_back))) |
| 73 | + print('\n'.join(not_following_back)) |
| 74 | + print("\n\nDo you want to UNFOLLOW them all??") |
| 75 | + ans1 = input("Y/N : ") |
| 76 | + if ans1 in ('Y', 'y'): |
| 77 | + InstaBot.unfollow(self, not_following_back) |
| 78 | + elif ans1 in ('N', 'n'): |
| 79 | + pass |
| 80 | + |
| 81 | + print("\n\n\n\nPeople whom you don't follow back ({}) :\n".format(len(you_not_following_back))) |
| 82 | + print('\n'.join(you_not_following_back)) |
| 83 | + print("\n\nDo you want to FOLLOW BACK them all??") |
| 84 | + ans2 = input("Y/N : ") |
| 85 | + if ans2 in ('Y', 'y'): |
| 86 | + InstaBot.follow_back(self, you_not_following_back) |
| 87 | + elif ans2 in ('N', 'n'): |
| 88 | + pass |
| 89 | + |
| 90 | + def _get_names(self): |
| 91 | + scroll_box = self.wait(EC.presence_of_element_located((By.XPATH, "/html/body/div[4]/div/div/div[2]"))) |
| 92 | + last_ht, ht = 0, 1 |
| 93 | + while last_ht != ht: |
| 94 | + last_ht = ht |
| 95 | + sleep(1) |
| 96 | + ht = self.driver.execute_script(""" |
| 97 | + arguments[0].scrollTo(0, arguments[0].scrollHeight); |
| 98 | + return arguments[0].scrollHeight; |
| 99 | + """, scroll_box) |
| 100 | + links = scroll_box.find_elements_by_tag_name('a') |
| 101 | + names = [name.text for name in links if name.text != ''] |
| 102 | + # close button |
| 103 | + self.driver.find_element_by_xpath("/html/body/div[4]/div/div/div[1]/div/div[2]/button") \ |
| 104 | + .click() |
| 105 | + return names |
| 106 | + |
| 107 | + def unfollow(self, not_following_back): |
| 108 | + self.driver.find_element_by_xpath("//img[@alt='Instagram']") \ |
| 109 | + .click() |
| 110 | + self.driver.maximize_window() |
| 111 | + for i in not_following_back: |
| 112 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(),'Search')]"))) \ |
| 113 | + .click() |
| 114 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//input[@placeholder='Search']"))) \ |
| 115 | + .click() |
| 116 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//a[@href='/{}/']".format(i)))) \ |
| 117 | + .click() |
| 118 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//span[@class='glyphsSpriteFriend_Follow u-__7']"))) \ |
| 119 | + .click() |
| 120 | + sleep(1) |
| 121 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Unfollow')]"))).click() |
| 122 | + sleep(1) |
| 123 | + self.driver.minimize_window() |
| 124 | + self.driver.find_element_by_xpath("//img[@alt='Instagram']") \ |
| 125 | + .click() |
| 126 | + |
| 127 | + def follow_back(self, you_not_following_back): |
| 128 | + self.driver.find_element_by_xpath("//img[@alt='Instagram']") \ |
| 129 | + .click() |
| 130 | + self.driver.maximize_window() |
| 131 | + for i in you_not_following_back: |
| 132 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(),'Search')]"))) \ |
| 133 | + .click() |
| 134 | + self.driver.find_element_by_xpath("//input[@placeholder='Search']") \ |
| 135 | + .send_keys(i) |
| 136 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//a[@href='/{}/']".format(i)))) \ |
| 137 | + .click() |
| 138 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Follow Back')]"))) \ |
| 139 | + .click() |
| 140 | + self.driver.minimize_window() |
| 141 | + self.driver.find_element_by_xpath("//img[@alt='Instagram']") \ |
| 142 | + .click() |
| 143 | + |
| 144 | + def spamming(self): |
| 145 | + recipients = input("Recipients (seperate by < , >)").split(",") |
| 146 | + print(recipients) |
| 147 | + msg = input("Message : ") |
| 148 | + count = int(input("How many messages : ")) |
| 149 | + print("\n----Be patient, your request is under process as you can spectate----\n") |
| 150 | + self.driver.find_element_by_xpath("//img[@alt='Instagram']") \ |
| 151 | + .click() |
| 152 | + self.driver.maximize_window() |
| 153 | + for i in recipients: |
| 154 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(),'Search')]"))) \ |
| 155 | + .click() |
| 156 | + self.driver.find_element_by_xpath("//input[@placeholder='Search']") \ |
| 157 | + .send_keys(i) |
| 158 | + self.wait(EC.presence_of_element_located((By.XPATH, "//a[@class='yCE8d ']"))) \ |
| 159 | + .click() |
| 160 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Message')]"))) \ |
| 161 | + .click() |
| 162 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//textarea[@placeholder='Message...']"))) \ |
| 163 | + .click() |
| 164 | + for _ in range(count): |
| 165 | + self.driver.find_element_by_xpath("//textarea[@placeholder='Message...']") \ |
| 166 | + .send_keys(msg) |
| 167 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Send')]"))) \ |
| 168 | + .click() |
| 169 | + self.driver.minimize_window() |
| 170 | + self.driver.find_element_by_xpath("//img[@alt='Instagram']") \ |
| 171 | + .click() |
| 172 | + |
| 173 | + def log_out(self): |
| 174 | + self.driver.find_element_by_xpath("//img[@alt='Instagram']") \ |
| 175 | + .click() |
| 176 | + self.wait(EC.element_to_be_clickable((By.XPATH, "//span[@class='_2dbep qNELH']"))) \ |
| 177 | + .click() |
| 178 | + log_out = "/html/body/div[1]/section/nav/div[2]/div/div/div[3]/div/div[5]/div[2]/div/div[2]/div[2]/div/div/div/div/div/div/div" |
| 179 | + self.wait(EC.element_to_be_clickable((By.XPATH, log_out))) \ |
| 180 | + .click() |
| 181 | + Users() |
| 182 | + |
| 183 | + |
| 184 | +class Users: |
| 185 | + |
| 186 | + def __init__(self): |
| 187 | + self.users = {} |
| 188 | + count = self.check_user() |
| 189 | + if count == 0: |
| 190 | + print("No user found, please add atleast 1 user") |
| 191 | + add_user() |
| 192 | + |
| 193 | + f = open("Users", "r") |
| 194 | + print("\nSelect user : ") |
| 195 | + for i in range(len(self.users)): |
| 196 | + print("( {} ) {}".format(i + 1, list(self.users.keys())[i])) |
| 197 | + print('''\n(a) To Add user (r) To Remove user (q) Quit application |
| 198 | + (re) Refresh the list(if the list didn't update)\n''') |
| 199 | + ans = input(":- ") |
| 200 | + try: |
| 201 | + if ans in ("Q",'q'): |
| 202 | + pass |
| 203 | + else: |
| 204 | + if ans in ("a","A"): |
| 205 | + add_user() |
| 206 | + self.check_user() |
| 207 | + Users() |
| 208 | + elif ans in ("R","r"): |
| 209 | + self.remove_user() |
| 210 | + Users() |
| 211 | + elif ans in ("re","RE","Re"): |
| 212 | + self.refresh() |
| 213 | + self.bot = InstaBot(list(self.users.keys())[int(ans) - 1],list(self.users.values())[int(ans) - 1]) |
| 214 | + f.close() |
| 215 | + self.start_cmd() |
| 216 | + except: |
| 217 | + print("Some error occurred, please enter numeric input to choose among the options.") |
| 218 | + Users() |
| 219 | + |
| 220 | + def check_user(self): |
| 221 | + key = "LO8QifH5rNwyNUhbs8GeDKExO1vToMA6AmdvaR1brgU=" |
| 222 | + with open("Users", "r") as f: |
| 223 | + data = f.readlines() |
| 224 | + if len(data) != 0: |
| 225 | + for i in range(0, len(data) - 1, 2): |
| 226 | + decrypted = Fernet(key).decrypt((str(data[i + 1])[0:-1].strip()).encode()) |
| 227 | + self.users[str(data[i])[0:-1].strip()] =str(decrypted.decode()) |
| 228 | + else: |
| 229 | + return 0 |
| 230 | + |
| 231 | + def remove_user(self): |
| 232 | + key = "LO8QifH5rNwyNUhbs8GeDKExO1vToMA6AmdvaR1brgU=" |
| 233 | + print("\n\nUser id's stored: ") |
| 234 | + usersl=list(self.users.keys()) |
| 235 | + for i in range(len(usersl)): |
| 236 | + print("( {} ) {}".format(i+1,usersl[i])) |
| 237 | + remove = int(input("User that to be removed: ")) |
| 238 | + self.users.pop(list(self.users.keys())[remove-1]) |
| 239 | + with open("Users", "w") as f: |
| 240 | + for i in self.users: |
| 241 | + usr=self.users.get(i) |
| 242 | + encrypted= Fernet(key).encrypt(usr.encode()) |
| 243 | + f.write(i + "\n" + encrypted.decode() + "\n") |
| 244 | + self.check_user() |
| 245 | + |
| 246 | + def start_cmd(self): |
| 247 | + print("\n\nChoose an action \n(1) Follow Back stats [OPTIONAL->Unfollow/Follow back]\n(2) Spam Bot\n(3) Change User\n") |
| 248 | + a = int(input(" :- ").strip()) |
| 249 | + try: |
| 250 | + if a == 1: |
| 251 | + print("\n----Please wait, this command will take several seconds----\n") |
| 252 | + self.bot.get_unfollowers() |
| 253 | + elif a == 2: |
| 254 | + self.bot.spamming() |
| 255 | + elif a == 3: |
| 256 | + self.bot.log_out() |
| 257 | + except: |
| 258 | + print("Some error occurred\n Please try again") |
| 259 | + input("\n\n") |
| 260 | + self.start_cmd() |
| 261 | + |
| 262 | + def refresh(self): |
| 263 | + self.check_user() |
| 264 | + Users() |
| 265 | + |
| 266 | + |
| 267 | +def add_user(): |
| 268 | + key="LO8QifH5rNwyNUhbs8GeDKExO1vToMA6AmdvaR1brgU=" |
| 269 | + with open("Users", "a") as f: |
| 270 | + a=int(input("No. of users to be added : ")) |
| 271 | + for i in range(a): |
| 272 | + username=input("Enter username {}: ".format(i+1)) |
| 273 | + f.write(username + '\n') |
| 274 | + password=input("Enter password of username( {} ): ".format(username)) |
| 275 | + encrypted = Fernet(key).encrypt(password.encode()) |
| 276 | + f.write(encrypted.decode()+'\n') |
| 277 | + Users().check_user() |
| 278 | + |
| 279 | + |
| 280 | +print(''' |
| 281 | + _____ _ ______ _ |
| 282 | +|_ _| | | | ___ \ | | |
| 283 | + | | _ __ ___ | |_ __ _ __ _ _ __ __ _ _ __ ___ | |_/ / ___ | |_ |
| 284 | + | | | '_ \ / __|| __|/ _` | / _` || '__|/ _` || '_ ` _ \ | ___ \ / _ \ | __| |
| 285 | + _| |_| | | |\__ \| |_| (_| || (_| || | | (_| || | | | | | | |_/ /| (_) || |_ |
| 286 | + \___/|_| |_||___/ \__|\__,_| \__, ||_| \__,_||_| |_| |_| \____/ \___/ \__| |
| 287 | + ==============================__/ |=========================================== |
| 288 | + |___/ By : YASH JOGLEKAR |
| 289 | + `````````````````` |
| 290 | +''') |
| 291 | + |
| 292 | +try: |
| 293 | + f = open("Users", "r") |
| 294 | + f.close() |
| 295 | +except: |
| 296 | + f = open("Users", "w") |
| 297 | + f.close() |
| 298 | +sleep(1.5) |
| 299 | +start = Users() |
| 300 | +print('\n------------------THANKS FOR USING MY BOT------------------\n') |
| 301 | +sleep(2) |
0 commit comments