def getPhotoDescription(self): 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" for i in dd: node = i.get('node') t.add_row([str(count), node.get('accessibility_caption')]) count += 1 if (self.writeFile): file_name = self.target + "_photodes.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t) else: pc.printout("Sorry! No results found :-(\n", pc.RED)
def getHashtags(self): if self.is_private: pc.printout("Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target hashtags...\n") text = [] only_id = {} a = None hashtags = [] counter = 1 while True: if a is None: self.api.getUserFeed(self.target_id) a = self.api.LastJson['items'] only_id = self.api.LastJson with open('data.json', 'w') as outfile: json.dump(only_id, outfile) 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 = i.get('caption', {}).get('text') text.append(c) counter = counter + 1 except AttributeError: pass if not 'next_max_id' in only_id: break hashtag_counter = {} for i in text: for j in i.split(): if j.startswith('#'): hashtags.append(j.encode('UTF-8')) for i in hashtags: if i in hashtag_counter: hashtag_counter[i] += 1 else: hashtag_counter[i] = 1 sortE = sorted(hashtag_counter.items(), key=lambda value: value[1], reverse=True) if self.writeFile: file_name = "output/" + self.target + "_hashtags.txt" file = open(file_name, "w") for k, v in sortE: file.write(str(v) + ". " + str(k.decode('utf-8')) + "\n") file.close() for k, v in sortE: print(str(v) + ". " + str(k.decode('utf-8')))
def getAddrs(self, id): pc.printout( "Searching for target address... this may take a few minutes...\n") addrs = self.__getAdressesTimes__(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 for address, time in addrs: t.add_row([str(i), address, time]) i = i + 1 if (self.writeFile): file_name = self.target + "_addrs.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t)
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" for i in followings: t.add_row([str(i['pk']), i['username'], i['full_name']]) if (self.writeFile): file_name = "output/" + self.target + "_followings.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t)
def getUserPropic(self): try: content = urllib.request.urlopen("https://www.instagram.com/" + str(self.target) + "/?__a=1") 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) data = json.load(content) URL = "" 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)
def getHashtags(self, id): pc.printout("Searching for target hashtags...\n") text = [] only_id = {} a = None #helper hashtags = [] counter = 1 while True: if (a == None): self.api.getUserFeed(id) a = self.api.LastJson['items'] #photos 00, 01, 02... only_id = self.api.LastJson #all LastJson with max_id param with open('data.json', 'w') as outfile: json.dump(only_id, outfile) else: self.api.getUserFeed( id, only_id['next_max_id']) #passing parameter max_id only_id = self.api.LastJson a = self.api.LastJson['items'] try: for i in a: c = i.get('caption', {}).get('text') text.append(c) #print str(counter) + ' ' + c counter = counter + 1 except AttributeError: pass if not 'next_max_id' in only_id: break hashtag_counter = {} for i in text: for j in i.split(): if j.startswith('#'): hashtags.append(j.encode('UTF-8')) for i in hashtags: if i in hashtag_counter: hashtag_counter[i] += 1 else: hashtag_counter[i] = 1 sortE = sorted(hashtag_counter.items(), key=lambda value: value[1], reverse=True) if (self.writeFile): file_name = self.target + "_hashtags.txt" file = open(file_name, "w") for k, v in sortE: file.write(str(v) + ". " + str(k.decode('utf-8')) + "\n") file.close() for k, v in sortE: print(str(v) + ". " + str(k.decode('utf-8')))
def getFollowings(self, id): pc.printout("Searching for target followings...\n") followings = self.__getUserFollowigs__(id) t = PrettyTable(['ID', 'Username', 'Full Name']) t.align["ID"] = "l" t.align["Username"] = "******" t.align["Full Name"] = "l" for i in followings: t.add_row([str(i['pk']), i['username'], i['full_name']]) print(t)
def __init__(self, target): self.target = target u = self.__getUsername__() p = self.__getPassword__() self.api = InstagramAPI(u, p) print("\nAttempt to login...\n") self.api.login() pc.printout("Logged as ", pc.GREEN) pc.printout(self.api.username, pc.CYAN) pc.printout(" (" + str(self.api.username_id) + ") ") pc.printout("target: ", pc.GREEN) pc.printout(str(self.target), pc.CYAN) print('\n')
def getCaptions(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") a = None counter = 0 captions = [] 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 item in a: 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 if not 'next_max_id' in only_id: break sys.stdout.write(" captions") sys.stdout.flush() if counter > 0: pc.printout("\nWoohoo! We found " + str(counter) + " captions\n", pc.GREEN) if self.writeFile: file_name = "output/" + self.target + "_captions.txt" file = open(file_name, "w") for s in captions: file.write(s + "\n") file.close() for s in captions: print(s + "\n") else: pc.printout("Sorry! No results found :-(\n", pc.RED) return
def getUserStories(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 = self.api.SendRequest(endpoint) data = self.api.LastJson counter = 0 if data['reel'] != 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 getAddrs(self, id): pc.printout("Searching for target address... this may take a few minutes...\n") addrs = self.__getAdressesTimes__(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 for address, time in addrs: t.add_row([str(i), address, time]) i = i + 1 print(t)
def getFollowings(self, id): pc.printout("Searching for target followings...\n") followings = self.__getUserFollowigs__(id) t = PrettyTable(['ID', 'Username', 'Full Name']) t.align["ID"] = "l" t.align["Username"] = "******" t.align["Full Name"] = "l" for i in followings: t.add_row([str(i['pk']), i['username'], i['full_name']]) if (self.writeFile): file_name = self.target + "_followings.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t)
def getTotalComments(self, id): pc.printout("Searching for target total comments...\n") comment_counter = 0 only_id = {} a = None counter = 0 while True: if (a == None): self.api.getUserFeed(id) a = self.api.LastJson['items'] only_id = self.api.LastJson else: self.api.getUserFeed(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() pc.printout(str(comment_counter), pc.MAGENTA) pc.printout(" comments in " + str(counter) + " posts\n")
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 for address, time in addrs: t.add_row([str(i), address, time]) i = i + 1 if (self.writeFile): file_name = "output/" + self.target + "_addrs.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t)
def getTotalComments(self, id): pc.printout("Searching for target total comments...\n") comment_counter = 0 only_id = {} a = None #helper counter = 0 while True: if (a == None): self.api.getUserFeed(id) a = self.api.LastJson['items']#photos 00, 01, 02... only_id = self.api.LastJson #all LastJson with max_id param else: self.api.getUserFeed(id, only_id['next_max_id']) #passing parameter 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 pc.printout(str(comment_counter), pc.MAGENTA) pc.printout(" comments in " + str(counter) + " posts\n")
def getMediaType(self, id): pc.printout("Searching for target captions...\n") a = None counter = 0 photo_counter = 0 video_counter = 0 while True: if (a == None): self.api.getUserFeed(id) a = self.api.LastJson['items'] only_id = self.api.LastJson else: self.api.getUserFeed(id, only_id['next_max_id']) only_id = self.api.LastJson a = self.api.LastJson['items'] try: for item in a: if "media_type" in item: if item["media_type"] == 1: photo_counter = photo_counter + 1 elif item["media_type"] == 2: video_counter = video_counter + 1 counter = counter + 1 sys.stdout.write("\rChecked %i" % counter) sys.stdout.flush() except AttributeError: pass except KeyError: pass if not 'next_max_id' in only_id: break 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) else: pc.printout("Sorry! No results found :-(\n", pc.RED) return
def getPeopleTaggedByUser(self, id): pc.printout("Searching for users tagged by target...\n") ids = [] username = [] full_name = [] post = [] only_id = {} a = None #helper counter = 1 while True: if (a == None): self.api.getUserFeed(id) a = self.api.LastJson['items']#photos 00, 01, 02... only_id = self.api.LastJson #all LastJson with max_id param else: self.api.getUserFeed(id, only_id['next_max_id']) #passing parameter max_id only_id = self.api.LastJson a = self.api.LastJson['items'] try: for i in a: 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: pass if not 'next_max_id' in only_id: break 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) for i in range(len(ids)): t.add_row([post[i], full_name[i], username[i], str(ids[i])]) print(t) else: pc.printout("Sorry! No results found :-(\n", pc.RED)
def getTotalLikes(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 only_id = {} a = None counter = 0 while True: if (a == 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('like_count')) like_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 + "_likes.txt" file = open(file_name, "w") file.write( str(like_counter) + " likes in " + str(counter) + " posts\n") file.close() pc.printout(str(like_counter), pc.MAGENTA) pc.printout(" likes in " + str(counter) + " posts\n")
def getTotalLikes(self, id): pc.printout("Searching for target total likes...\n") like_counter = 0 only_id = {} a = None #helper counter = 0 while True: if (a == None): self.api.getUserFeed(id) a = self.api.LastJson['items'] #photos 00, 01, 02... only_id = self.api.LastJson #all LastJson with max_id param else: self.api.getUserFeed( id, only_id['next_max_id']) #passing parameter max_id only_id = self.api.LastJson a = self.api.LastJson['items'] try: for i in a: c = int(i.get('like_count')) like_counter += c counter = counter + 1 except AttributeError: pass if not 'next_max_id' in only_id: break if (self.writeFile): file_name = self.target + "_likes.txt" file = open(file_name, "w") file.write( str(like_counter) + " likes in " + str(counter) + " posts\n") file.close() pc.printout(str(like_counter), pc.MAGENTA) pc.printout(" likes in " + str(counter) + " posts\n")
def getUserPhoto(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return limit = -1 pc.printout("How many photos you want to download (default all): ", pc.YELLOW) l = input() try: if l == "": pc.printout("Downloading all photos avaible...\n") else: limit = int(l) pc.printout("Downloading " + l + " photos...\n") except ValueError: pc.printout("Wrong value entered\n", pc.RED) return a = None counter = 0 while True: if (a == 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 item in a: if counter == limit: break if "image_versions2" in item: counter = counter + 1 url = item["image_versions2"]["candidates"][0]["url"] photo_id = item["id"] end = "output/" + self.target + "_" + photo_id + ".jpg" urllib.request.urlretrieve(url, end) sys.stdout.write("\rDownloaded %i" % counter) sys.stdout.flush() else: carousel = item["carousel_media"] for i in carousel: if counter == limit: break counter = counter + 1 url = i["image_versions2"]["candidates"][0]["url"] photo_id = i["id"] end = "output/" + self.target + "_" + photo_id + ".jpg" urllib.request.urlretrieve(url, end) sys.stdout.write("\rDownloaded %i" % counter) sys.stdout.flush() except AttributeError: pass except KeyError: pass if not 'next_max_id' in only_id: break sys.stdout.write(" photos") sys.stdout.flush() pc.printout( "\nWoohoo! We downloaded " + str(counter) + " photos (saved in output/ folder) \n", pc.GREEN)
def getUserInfo(self): try: content = urllib.request.urlopen("https://www.instagram.com/" + str(self.target) + "/?__a=1") 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) data = json.load(content) data = data['graphql']['user'] pc.printout("[ID] ", pc.GREEN) pc.printout(str(data['id']) + '\n') pc.printout("[FULL NAME] ", pc.RED) pc.printout(str(data['full_name']) + '\n') pc.printout("[BIOGRAPHY] ", pc.CYAN) pc.printout(str(data['biography']) + '\n') pc.printout("[FOLLOWED] ", pc.GREEN) pc.printout(str(data['edge_followed_by']['count']) + '\n') pc.printout("[FOLLOW] ", pc.BLUE) pc.printout(str(data['edge_follow']['count']) + '\n') pc.printout("[BUSINESS ACCOUNT] ", pc.RED) pc.printout(str(data['is_business_account']) + '\n') if data['is_business_account'] == True: pc.printout("[BUSINESS CATEGORY] ") pc.printout(str(data['business_category_name']) + '\n') pc.printout("[VERIFIED ACCOUNT] ", pc.CYAN) pc.printout(str(data['is_verified']) + '\n')
def getPeopleTaggedByUser(self): pc.printout("Searching for users tagged by target...\n") ids = [] username = [] full_name = [] post = [] only_id = {} a = None counter = 1 while True: if (a == 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: 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 not 'next_max_id' in only_id: break 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) for i in range(len(ids)): t.add_row([post[i], full_name[i], username[i], str(ids[i])]) if (self.writeFile): file_name = "output/" + self.target + "_tagged.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t) else: pc.printout("Sorry! No results found :-(\n", pc.RED)
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 0.2 - Developed by Giuseppe Criscione - 2019\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")
def cmdlist(): #print("set <username>\t Set user to analize") #print("clear\t\t Remove the user setted") pc.printout("FILE=y/n\t\t") print("Write all output in a '<target username>_<command>.txt' file'") pc.printout("FILE=y\t\t") print("Write all output in a '<target username>_<command>.txt' file'") pc.printout("info\t\t") print("Get target info") pc.printout("addrs\t\t") print("Get all registered addressed by target photos") pc.printout("followers\t") print("Get target followers") pc.printout("followings\t") print("Get users followed by target") pc.printout("hashtags\t") print("Get hashtags used by target") pc.printout("likes\t\t") print("Get total likes of target's posts") pc.printout("comments\t") print("Get total comments of target's posts") pc.printout("tagged\t\t") print("Get list of users tagged by target") pc.printout("photodes\t") print("Get description of target's photos")
printlogo() parser = argparse.ArgumentParser() parser.add_argument( 'id', type=str, # var = id help='username') args = parser.parse_args() api = Osintgram(args.id) id = api.getUserID(args.id) 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": cmdlist() elif cmd == "addrs": api.getAddrs(id) elif cmd == "followers": api.getFollowers(id) elif cmd == "followings": api.getFollowings(id) elif cmd == "hashtags": api.getHashtags(id) elif cmd == "likes":
def __printTargetBanner__(self): pc.printout("\nLogged as ", pc.GREEN) pc.printout(self.api.username, pc.CYAN) pc.printout(" (" + str(self.api.username_id) + ") ") pc.printout("target: ", pc.GREEN) pc.printout(str(self.target), pc.CYAN) pc.printout(" (private: " + str(self.is_private) + ")") print('\n')
def changeTarget(self): pc.printout("Insert new target username: ", pc.YELLOW) l = input() self.setTarget(l) return
def setWriteFile(self, flag): if flag: pc.printout("Write to file: ") pc.printout("enabled", pc.GREEN) pc.printout("\n") else: pc.printout("Write to file: ") pc.printout("disabled", pc.RED) pc.printout("\n") self.writeFile = flag
def setWriteFile(self, bool): if (bool): pc.printout("Write to file: ") pc.printout("enabled", pc.GREEN) pc.printout("\n") else: pc.printout("Write to file: ") pc.printout("disabled", pc.RED) pc.printout("\n") self.writeFile = bool
def cmdlist(): #print("set <username>\t Set user to analize") #print("clear\t\t Remove the user setted") pc.printout("FILE=y/n\t") print("Enable/disable output in a '<target username>_<command>.txt' file'") pc.printout("info\t\t") print("Get target info") pc.printout("addrs\t\t") print("Get all registered addressed by target photos") pc.printout("followers\t") print("Get target followers") pc.printout("followings\t") print("Get users followed by target") pc.printout("hashtags\t") print("Get hashtags used by target") pc.printout("likes\t\t") print("Get total likes of target's posts") pc.printout("comments\t") print("Get total comments of target's posts") pc.printout("tagged\t\t") print("Get list of users tagged by target") 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("captions\t") print("Get target's photos captions") pc.printout("mediatype\t") print("Get target's posts type (photo or video)") pc.printout("propic\t\t") print("Download target's profile picture") pc.printout("stories\t\t") print("Download target's sories")