def get_user_propic(self): try: endpoint = 'users/{user_id!s}/full_detail_info/'.format( **{'user_id': self.target}) content = self.api._call_api(endpoint) data = content['user_detail']['user'] if "hd_profile_pic_url_info" in data: URL = data["hd_profile_pic_url_info"]['url'] else: #get better quality photo items = len(data['hd_profile_pic_versions']) URL = data["hd_profile_pic_versions"][items - 1]['url'] if URL != "": end = "output/" + self.target + "_propic.jpg" urllib.request.urlretrieve(URL, end) pc.printout("Target propic saved in output folder\n", pc.GREEN) else: pc.printout("Sorry! No results found :-(\n", pc.RED) except ClientError as e: print(e) print("An error occured... exit") exit(2)
def get_user_propic(self): try: content = urllib.request.urlopen("https://www.instagram.com/" + str(self.target) + "/?__a=1") data = json.load(content) uurl = data["graphql"]["user"] if "profile_pic_url_hd" in uurl: URL = data["graphql"]["user"]["profile_pic_url_hd"] else: URL = data["graphql"]["user"]["profile_pic_url"] if URL != "": end = "output/" + self.target + "_propic.jpg" urllib.request.urlretrieve(URL, end) pc.printout("Target propic saved in output folder\n", pc.GREEN) else: pc.printout("Sorry! No results found :-(\n", pc.RED) except urllib.error.HTTPError as err: if err.code == 404: print("Oops... " + str(self.target) + " non exist, please enter a valid username.") sys.exit(2)
def check_private_profile(self): if self.is_private and not self.following: pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return True return False
def __getUsername__(self): try: u = open("config/username.conf", "r").read() u = u.replace("\n", "") return u except FileNotFoundError: pc.printout("Error: file \"config/username.conf\" not found!", pc.RED) pc.printout("\n") sys.exit(0)
def __getPassword__(self): try: p = open("config/pw.conf", "r").read() p = p.replace("\n", "") return p except FileNotFoundError: pc.printout("Error: file \"config/pw.conf\" not found!", pc.RED) pc.printout("\n") sys.exit(0)
def get_followings(self): if self.check_private_profile(): return pc.printout("Searching for target followings...\n") followings = [] rank_token = AppClient.generate_uuid() data = self.api.user_following(str(self.target_id), rank_token=rank_token) for user in data['users']: u = { 'id': user['pk'], 'username': user['username'], 'full_name': user['full_name'] } followings.append(u) t = PrettyTable(['ID', 'Username', 'Full Name']) t.align["ID"] = "l" t.align["Username"] = "******" t.align["Full Name"] = "l" json_data = {} followings_list = [] for node in followings: t.add_row([str(node['id']), node['username'], node['full_name']]) if self.jsonDump: follow = { 'id': node['id'], 'username': node['username'], 'full_name': node['full_name'] } followings_list.append(follow) if self.writeFile: file_name = "output/" + self.target + "_followings.txt" file = open(file_name, "w") file.write(str(t)) file.close() if self.jsonDump: json_data['followings'] = followings_list json_file_name = "output/" + self.target + "_followings.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) print(t)
def login(self, u, p): try: settings_file = "config/settings.json" if not os.path.isfile(settings_file): # settings file does not exist print('Unable to find file: {0!s}'.format(settings_file)) # login new self.api = AppClient( auto_patch=True, authenticate=True, username=u, password=p, on_login=lambda x: self.onlogin_callback(x, settings_file)) else: with open(settings_file) as file_data: cached_settings = json.load(file_data, object_hook=self.from_json) # print('Reusing settings: {0!s}'.format(settings_file)) # reuse auth settings self.api = AppClient( username=u, password=p, settings=cached_settings, on_login=lambda x: self.onlogin_callback(x, settings_file)) except (ClientCookieExpiredError, ClientLoginRequiredError) as e: print('ClientCookieExpiredError/ClientLoginRequiredError: {0!s}'. format(e)) # Login expired # Do relogin but use default ua, keys and such self.api = AppClient( auto_patch=True, authenticate=True, username=u, password=p, on_login=lambda x: self.onlogin_callback(x, settings_file)) except ClientError as e: #pc.printout('ClientError {0!s} (Code: {1:d}, Response: {2!s})'.format(e.msg, e.code, e.error_response), pc.RED) error = json.loads(e.error_response) pc.printout(error['message'], pc.RED) pc.printout("\n") if 'challenge' in error: print("Please follow this link to complete the challenge: " + error['challenge']['url']) exit(9)
def get_photo_description(self): if self.check_private_profile(): return content = requests.get("https://www.instagram.com/" + str(self.target) + "/?__a=1") data = content.json() dd = data['graphql']['user']['edge_owner_to_timeline_media']['edges'] if len(dd) > 0: pc.printout( "\nWoohoo! We found " + str(len(dd)) + " descriptions\n", pc.GREEN) count = 1 t = PrettyTable(['Photo', 'Description']) t.align["Photo"] = "l" t.align["Description"] = "l" json_data = {} descriptions_list = [] for i in dd: node = i.get('node') descr = node.get('accessibility_caption') t.add_row([str(count), descr]) if self.jsonDump: description = {'description': descr} descriptions_list.append(description) count += 1 if self.writeFile: file_name = "output/" + self.target + "_photodes.txt" file = open(file_name, "w") file.write(str(t)) file.close() if self.jsonDump: json_data['descriptions'] = descriptions_list json_file_name = "output/" + self.target + "_descriptions.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) print(t) else: pc.printout("Sorry! No results found :-(\n", pc.RED)
def get_total_likes(self): if self.is_private: pc.printout("Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target total likes...\n") like_counter = 0 posts = 0 data = self.__get_feed__() for post in data: like_counter += post['like_count'] if self.writeFile: file_name = "output/" + self.target + "_likes.txt" file = open(file_name, "w") file.write(str(like_counter) + " likes in " + str(like_counter) + " posts\n") file.close() if self.jsonDump: json_data = { 'like_counter': like_counter, 'posts': like_counter } json_file_name = "output/" + self.target + "_likes.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) pc.printout(str(like_counter), pc.MAGENTA) pc.printout(" likes in " + str(posts) + " posts\n")
def check_private_profile(self): if self.is_private and not self.following: pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) send = input("Do you want send a follow request? [Y/N]: ") if send.lower() == "y": self.api.friendships_create(self.target_id) print( "Sent a follow request to target. Use this command after target accepting the request." ) return True return False
def get_user_stories(self): if self.is_private: pc.printout("Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target stories...\n") endpoint = 'feed/user/{id!s}/story/'.format(**{'id': self.target_id}) content = urllib.request.urlopen("https://www.instagram.com/" + endpoint) data = json.load(content) counter = 0 if data['reel'] is not None: # no stories avaibile for i in data['reel']['items']: story_id = i["id"] if i["media_type"] == 1: # it's a photo url = i['image_versions2']['candidates'][0]['url'] end = "output/" + self.target + "_" + story_id + ".jpg" urllib.request.urlretrieve(url, end) counter += 1 elif i["media_type"] == 2: # it's a gif or video url = i['video_versions'][0]['url'] end = "output/" + self.target + "_" + story_id + ".mp4" urllib.request.urlretrieve(url, end) counter += 1 if counter > 0: pc.printout(str(counter) + " target stories saved in output folder\n", pc.GREEN) else: pc.printout("Sorry! No results found :-(\n", pc.RED)
def get_captions(self): if self.is_private: pc.printout("Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target captions...\n") captions = [] data = self.__get_feed__() counter = 0 try: for item in data: if "caption" in item: if item["caption"] is not None: text = item["caption"]["text"] captions.append(text) counter = counter + 1 sys.stdout.write("\rFound %i" % counter) sys.stdout.flush() except AttributeError: pass except KeyError: pass json_data = {} if counter > 0: pc.printout("\nWoohoo! We found " + str(counter) + " captions\n", pc.GREEN) file = None if self.writeFile: file_name = "output/" + self.target + "_captions.txt" file = open(file_name, "w") for s in captions: print(s + "\n") if self.writeFile: file.write(s + "\n") if self.jsonDump: json_data['captions'] = captions json_file_name = "output/" + self.target + "_followings.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) if file is not None: file.close() else: pc.printout("Sorry! No results found :-(\n", pc.RED) return
def getUsername(): try: username = config["Credentials"]["username"] if username == '': pc.printout( 'Error: "username" field cannot be blank in "config/credentials.ini"\n', pc.RED) sys.exit(0) return username except KeyError: pc.printout( 'Error: missing "username" field in "config/credentials.ini"\n', pc.RED) sys.exit(0)
def getPassword(): try: password = config["Credentials"]["password"] if password == '': pc.printout( 'Error: "password" field cannot be blank in "config/credentials.ini"\n', pc.RED) sys.exit(0) return password except KeyError: pc.printout( 'Error: missing "password" field in "config/credentials.ini"\n', pc.RED) sys.exit(0)
def getFollowings(self): if self.is_private: pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target followings...\n") followings = self.__getUserFollowigs__(self.target_id) t = PrettyTable(['ID', 'Username', 'Full Name']) t.align["ID"] = "l" t.align["Username"] = "******" t.align["Full Name"] = "l" json_data = {} followings_list = [] for i in followings: t.add_row([str(i['pk']), i['username'], i['full_name']]) if self.jsonDump: follow = { 'id': i['pk'], 'username': i['username'], 'full_name': i['full_name'] } followings_list.append(follow) if self.writeFile: file_name = "output/" + self.target + "_followings.txt" file = open(file_name, "w") file.write(str(t)) file.close() if self.jsonDump: json_data['followings'] = followings_list json_file_name = "output/" + self.target + "_followings.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) print(t)
def register_income(): category = input(""" Please select a category for register income: Categories: ¯¯¯¯¯¯¯¯¯¯¯ 1) Salary 👷 2) Profit 📈 3) Other 🧮 0) Go back """) if category == "1": category = "Salary" elif category == "2": category = "Profit" elif category == "3": category = "Other" elif category == "0": main() else: pc.printout("The option is incorrect, please select a correct option", pc.RED) register_income() date = input(""" Please insert the date of income (MM/DD/YYYY): """) amount = input(""" Please insert the amount of income: $""") description = input(""" Please insert a description of the income: """) incomes.add({ "category": category, "name": description, "date": date, "amount": amount })
def get_total_comments(self): if self.check_private_profile(): return pc.printout("Searching for target total comments...\n") comments_counter = 0 posts = 0 data = self.__get_feed__() for post in data: comments_counter += post['comment_count'] posts += 1 if self.writeFile: file_name = "output/" + self.target + "_comments.txt" file = open(file_name, "w") file.write( str(comments_counter) + " comments in " + str(posts) + " posts\n") file.close() if self.jsonDump: json_data = {'comment_counter': comments_counter, 'posts': posts} json_file_name = "output/" + self.target + "_comments.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) pc.printout(str(comments_counter), pc.MAGENTA) pc.printout(" comments in " + str(posts) + " posts\n")
def get_user_stories(self): if self.check_private_profile(): return pc.printout("Searching for target stories...\n") data = self.api.user_reel_media(str(self.target_id)) counter = 0 if data['items'] is not None: # no stories avaibile counter = data['media_count'] for i in data['items']: story_id = i["id"] if i["media_type"] == 1: # it's a photo url = i['image_versions2']['candidates'][0]['url'] end = "output/" + self.target + "_" + story_id + ".jpg" urllib.request.urlretrieve(url, end) elif i["media_type"] == 2: # it's a gif or video url = i['video_versions'][0]['url'] end = "output/" + self.target + "_" + story_id + ".mp4" urllib.request.urlretrieve(url, end) if counter > 0: pc.printout( str(counter) + " target stories saved in output folder\n", pc.GREEN) else: pc.printout("Sorry! No results found :-(\n", pc.RED)
def getTotalComments(self): if self.is_private: pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target total comments...\n") comment_counter = 0 only_id = {} a = None counter = 0 while True: if a is None: self.api.getUserFeed(self.target_id) a = self.api.LastJson['items'] only_id = self.api.LastJson else: self.api.getUserFeed(self.target_id, only_id['next_max_id']) only_id = self.api.LastJson a = self.api.LastJson['items'] try: for i in a: c = int(i.get('comment_count')) comment_counter += c counter = counter + 1 except AttributeError: pass if not 'next_max_id' in only_id: break if self.writeFile: file_name = "output/" + self.target + "_comments.txt" file = open(file_name, "w") file.write( str(comment_counter) + " comments in " + str(counter) + " posts\n") file.close() if self.jsonDump: json_data = {'comment_counter': comment_counter, 'posts': counter} json_file_name = "output/" + self.target + "_comments.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) pc.printout(str(comment_counter), pc.MAGENTA) pc.printout(" comments in " + str(counter) + " posts\n")
def get_media_type(self): if self.is_private: pc.printout("Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target captions...\n") counter = 0 photo_counter = 0 video_counter = 0 data = self.__get_feed__() for post in data: if "media_type" in post: if post["media_type"] == 1: photo_counter = photo_counter + 1 elif post["media_type"] == 2: video_counter = video_counter + 1 counter = counter + 1 sys.stdout.write("\rChecked %i" % counter) sys.stdout.flush() sys.stdout.write(" posts") sys.stdout.flush() if counter > 0: if self.writeFile: file_name = "output/" + self.target + "_mediatype.txt" file = open(file_name, "w") file.write(str(photo_counter) + " photos and " + str(video_counter) + " video posted by target\n") file.close() pc.printout("\nWoohoo! We found " + str(photo_counter) + " photos and " + str(video_counter) + " video posted by target\n", pc.GREEN) if self.jsonDump: json_data = { "photos": photo_counter, "videos": video_counter } json_file_name = "output/" + self.target + "_mediatype.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) else: pc.printout("Sorry! No results found :-(\n", pc.RED)
def get_people_who_commented(self): if self.is_private: pc.printout("Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for users who commented...\n") data = self.__get_feed__() users = [] for post in data: comments = self.__get_comments__(post['id']) for comment in comments: if not any(u['id'] == comment['user']['pk'] for u in users): user = { 'id': comment['user']['pk'], 'username': comment['user']['username'], 'full_name': comment['user']['full_name'], 'counter': 1 } users.append(user) else: for user in users: if user['id'] == comment['user']['pk']: user['counter'] += 1 break if len(users) > 0: ssort = sorted(users, key=lambda value: value['counter'], reverse=True) json_data = {} t = PrettyTable() t.field_names = ['Comments', 'ID', 'Username', 'Full Name'] t.align["Comments"] = "l" t.align["ID"] = "l" t.align["Username"] = "******" t.align["Full Name"] = "l" for u in ssort: t.add_row([str(u['counter']), u['id'], u['username'], u['full_name']]) print(t) if self.writeFile: file_name = "output/" + self.target + "_users_who_commented.txt" file = open(file_name, "w") file.write(str(t)) file.close() if self.jsonDump: json_data['users_who_commented'] = ssort json_file_name = "output/" + self.target + "_users_who_commented.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) else: pc.printout("Sorry! No results found :-(\n", pc.RED)
def get_user(self, username): try: endpoint = 'users/{user_id!s}/full_detail_info/'.format( **{'user_id': self.target}) content = self.api._call_api(endpoint) if self.writeFile: file_name = "output/" + self.target + "_user_id.txt" file = open(file_name, "w") file.write(str(content['user_detail']['user']['pk'])) file.close() user = dict() user['id'] = content['user_detail']['user']['pk'] user['is_private'] = content['user_detail']['user']['is_private'] return user except ClientError as e: pc.printout( "Oops... " + str(self.target) + " non exist, please enter a valid username.", pc.RED) pc.printout("\n") exit(2)
def getPhotoDescription(self): if self.is_private: pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return content = self.api.SendRequest2(self.target + '/?__a=1') data = self.api.LastJson dd = data['graphql']['user']['edge_owner_to_timeline_media']['edges'] if len(dd) > 0: pc.printout( "\nWoohoo! We found " + str(len(dd)) + " descriptions\n", pc.GREEN) count = 1 t = PrettyTable(['Photo', 'Description']) t.align["Photo"] = "l" t.align["Description"] = "l" json_data = {} descriptions_list = [] for i in dd: node = i.get('node') descr = node.get('accessibility_caption') t.add_row([str(count), descr]) if self.jsonDump: description = {'description': descr} descriptions_list.append(description) count += 1 if self.writeFile: file_name = "output/" + self.target + "_photodes.txt" file = open(file_name, "w") file.write(str(t)) file.close() if self.jsonDump: json_data['descriptions'] = descriptions_list json_file_name = "output/" + self.target + "_descriptions.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) print(t) else: pc.printout("Sorry! No results found :-(\n", pc.RED)
def getAddrs(self): if self.is_private: pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout( "Searching for target address... this may take a few minutes...\n") addrs = self.__getAdressesTimes__(self.target_id) t = PrettyTable() t.field_names = ['Post', 'Address', 'time'] t.align["Post"] = "l" t.align["Address"] = "l" t.align["Time"] = "l" pc.printout("\nWoohoo! We found " + str(len(addrs)) + " addresses\n", pc.GREEN) i = 1 json_data = {} addrs_list = [] for address, time in addrs: t.add_row([str(i), address, time]) if self.jsonDump: addr = {'address': address, 'time': time} addrs_list.append(addr) i = i + 1 if self.writeFile: file_name = "output/" + self.target + "_addrs.txt" file = open(file_name, "w") file.write(str(t)) file.close() if self.jsonDump: json_data['address'] = addrs_list json_file_name = "output/" + self.target + "_addrs.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) print(t)
def signal_handler(sig, frame): pc.printout("\nGoodbye!\n", pc.RED) sys.exit(0)
def cmdlist(): pc.printout("FILE=y/n\t") print("Enable/disable output in a '<target username>_<command>.txt' file'") pc.printout("JSON=y/n\t") print( "Enable/disable export in a '<target username>_<command>.json' file'") pc.printout("addrs\t\t") print("Get all registered addressed by target photos") pc.printout("captions\t") print("Get target's photos captions") pc.printout("comments\t") print("Get total comments of target's posts") pc.printout("followers\t") print("Get target followers") pc.printout("followings\t") print("Get users followed by target") pc.printout("fwersemail\t") print("Get email of target followers") pc.printout("fwingsemail\t") print("Get email of users followed by target") pc.printout("hashtags\t") print("Get hashtags used by target") pc.printout("info\t\t") print("Get target info") pc.printout("likes\t\t") print("Get total likes of target's posts") pc.printout("mediatype\t") print("Get target's posts type (photo or video)") pc.printout("photodes\t") print("Get description of target's photos") pc.printout("photos\t\t") print("Download target's photos in output folder") pc.printout("propic\t\t") print("Download target's profile picture") pc.printout("stories\t\t") print("Download target's sories") pc.printout("tagged\t\t") print("Get list of users tagged by target") pc.printout("target\t\t") print("Set new target") pc.printout("wcommented\t") print("Get a list of user who commented target's photos") pc.printout("wtagged\t\t") print("Get a list of user who tagged target")
def printlogo(): pc.printout( "________ .__ __ \n", pc.YELLOW) pc.printout( "\_____ \ _____|__| _____/ |_ ________________ _____ \n", pc.YELLOW) pc.printout( " / | \ / ___/ |/ \ __\/ ___\_ __ \__ \ / \ \n", pc.YELLOW) pc.printout( "/ | \\\___ \| | | \ | / /_/ > | \// __ \| Y Y \\\n", pc.YELLOW) pc.printout( "\_______ /____ >__|___| /__| \___ /|__| (____ /__|_| /\n", pc.YELLOW) pc.printout( " \/ \/ \/ /_____/ \/ \/ \n", pc.YELLOW) print('\n') pc.printout("Version 1.0.1 - Developed by Giuseppe Criscione\n\n", pc.YELLOW) pc.printout("Type 'list' to show all allowed commands\n") pc.printout( "Type 'FILE=y' to save results to files like '<target username>_<command>.txt (deafult is disabled)'\n" ) pc.printout("Type 'FILE=n' to disable saving to files'\n") pc.printout( "Type 'JSON=y' to export results to a JSON files like '<target username>_<command>.json (deafult is " "disabled)'\n") pc.printout("Type 'JSON=n' to disable exporting to files'\n")
help='username') parser.add_argument('-j', '--json', help='save commands output as JSON file', action='store_true') parser.add_argument('-f', '--file', help='save output in a file', action='store_true') args = parser.parse_args() api = Osintgram(args.id, args.file, args.json) while True: pc.printout("Run a command: ", pc.YELLOW) cmd = input() if cmd == "quit" or cmd == "exit": pc.printout("Goodbye!\n", pc.RED) sys.exit(0) elif cmd == "list" or cmd == "help": cmdlist() elif cmd == "addrs": api.get_addrs() elif cmd == "captions": api.get_captions() elif cmd == "comments": api.get_total_comments() elif cmd == "followers": api.get_followers() elif cmd == "followings":
def __printTargetBanner__(self): pc.printout("\nLogged as ", pc.GREEN) pc.printout(self.api.username, pc.CYAN) pc.printout(". Target: ", pc.GREEN) pc.printout(str(self.target), pc.CYAN) pc.printout(" [" + str(self.target_id) + "]") if self.is_private: pc.printout(" [PRIVATE PROFILE]", pc.BLUE) if self.following: pc.printout(" [FOLLOWING]", pc.GREEN) else: pc.printout(" [NOT FOLLOWING]", pc.RED) print('\n')
def get_people_tagged_by_user(self): pc.printout("Searching for users tagged by target...\n") ids = [] username = [] full_name = [] post = [] counter = 1 data = self.__get_feed__() try: for i in data: if "usertags" in i: c = i.get('usertags').get('in') for cc in c: if cc.get('user').get('pk') not in ids: ids.append(cc.get('user').get('pk')) username.append(cc.get('user').get('username')) full_name.append(cc.get('user').get('full_name')) post.append(1) else: index = ids.index(cc.get('user').get('pk')) post[index] += 1 counter = counter + 1 except AttributeError as ae: pc.printout("\nERROR: an error occurred: ", pc.RED) print(ae) print("") pass if len(ids) > 0: t = PrettyTable() t.field_names = ['Posts', 'Full Name', 'Username', 'ID'] t.align["Posts"] = "l" t.align["Full Name"] = "l" t.align["Username"] = "******" t.align["ID"] = "l" pc.printout( "\nWoohoo! We found " + str(len(ids)) + " (" + str(counter) + ") users\n", pc.GREEN) json_data = {} tagged_list = [] for i in range(len(ids)): t.add_row([post[i], full_name[i], username[i], str(ids[i])]) if self.jsonDump: tag = { 'post': post[i], 'full_name': full_name[i], 'username': username[i], 'id': ids[i] } tagged_list.append(tag) if self.writeFile: file_name = "output/" + self.target + "_tagged.txt" file = open(file_name, "w") file.write(str(t)) file.close() if self.jsonDump: json_data['tagged'] = tagged_list json_file_name = "output/" + self.target + "_tagged.json" with open(json_file_name, 'w') as f: json.dump(json_data, f) print(t) else: pc.printout("Sorry! No results found :-(\n", pc.RED)