Projects STRLCPY Osintgram Commits 2869d2c6
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    README.md
    1  -[![](https://img.shields.io/badge/version-1.0-green)](https://github.com/Datalux/Osintgram/releases/tag/1.0)
     1 +[![](https://img.shields.io/badge/version-1.1-green)](https://github.com/Datalux/Osintgram/releases/tag/1.1)
    2 2  [![](https://img.shields.io/badge/license-GPLv3-blue)](https://img.shields.io/badge/license-GPLv3-blue)
    3 3  [![](https://img.shields.io/badge/language-Python3-red)](https://img.shields.io/badge/language-Python3-red)
    4 4  [![](https://img.shields.io/badge/Telegram-Channel-blue.svg)](https://t.me/osintgram)
    skipped 12 lines
    17 17  - followings Get users followed by target
    18 18  - fwersemail Get email of target followers
    19 19  - fwingsemail Get email of users followed by target
     20 +- fwersnumber Get phone number of target followers
     21 +- fwingsnumber Get phone number of users followed by target
    20 22  - hashtags Get hashtags used by target
    21 23  - info Get target info
    22 24  - likes Get total likes of target's posts
    skipped 8 lines
    31 33  ```
    32 34  You can find detailed commands usage [here](doc/COMMANDS.md).
    33 35   
    34  -[**Latest version**](https://github.com/Datalux/Osintgram/releases/tag/1.0.1) |
     36 +[**Latest version**](https://github.com/Datalux/Osintgram/releases/tag/1.1) |
    35 37  [CHANGELOG](doc/CHANGELOG.md)
    36 38   
    37 39  ## Tools
    skipped 53 lines
  • ■ ■ ■ ■ ■ ■
    doc/CHANGELOG.md
    1 1  # Changelog
    2 2   
     3 +## [1.1](https://github.com/Datalux/Osintgram/releases/tag/1.1)
     4 +**Enhancements**
     5 +- Improved command parser (#86)
     6 +- Improved errors handling (8bd1abc)
     7 +- Add new line when input command is empty (f5211eb)
     8 +- Added new commands to catch phone number of users (#111)
     9 +- Added support for Windows (#100)
     10 + 
     11 + 
     12 +**Bug fixes**
     13 +- Fix commands output limit bug (#87)
     14 +- Fix setting target with "." in username (9082990)
     15 +- Readline installing error (#94 )
     16 + 
     17 + 
    3 18  ## [1.0.1](https://github.com/Datalux/Osintgram/releases/tag/1.0.1)
    4 19  **Bug fixes**
    5 20  - Set itself as target by param
    skipped 80 lines
    86 101   
    87 102  **Bug fixes**
    88 103   
    89  -- added a check if target has a private profile to avoid tool crash (#10)
     104 +- added a check if the target has a private profile to avoid tool crash (#10)
    90 105  - fixed `tagged` bug (#5)
    91 106   
    92 107  ## [0.3](https://github.com/Datalux/Osintgram/releases/tag/0.3)
    skipped 20 lines
  • ■ ■ ■ ■ ■ ■
    doc/COMMANDS.md
    skipped 51 lines
    52 52  ### fwingsemail
    53 53  Return a list of emails of user followed by target
    54 54   
     55 +### fwersnumber
     56 +Return a list of phone number of target followers
     57 + 
     58 +### fwingsnumber
     59 +Return a list of phone number of user followed by target
     60 + 
    55 61  ### hashtags
    56 62  Return a list with all hashtag used by target in his photos
    57 63   
    skipped 63 lines
  • ■ ■ ■ ■ ■ ■
    main.py
    1  -#!/usr/bin/env python
     1 +#!/usr/bin/env python3
    2 2  # -*- coding: utf-8 -*-
    3 3   
    4 4  from src.Osintgram import Osintgram
    skipped 1 lines
    6 6  from src import printcolors as pc
    7 7  import sys
    8 8  import signal
    9  -import readline
     9 + 
     10 +is_windows = False
    10 11   
    11  -commands = ["quit", "exit", "list", "help", "addrs", "captions", "comments", "followers",
    12  - "followings", "fwersemail", "fwingsemail", "hashtags", "info", "likes",
    13  - "mediatype", "photodes", "photos", "propic", "stories", "tagged", "target",
    14  - "wcommented", "wtagged"]
     12 +try:
     13 + import gnureadline
     14 +except:
     15 + is_windows = True
     16 + import pyreadline
    15 17   
    16 18   
    17 19  def printlogo():
    skipped 4 lines
    22 24   pc.printout("\_______ /____ >__|___| /__| \___ /|__| (____ /__|_| /\n", pc.YELLOW)
    23 25   pc.printout(" \/ \/ \/ /_____/ \/ \/ \n", pc.YELLOW)
    24 26   print('\n')
    25  - pc.printout("Version 1.0.1 - Developed by Giuseppe Criscione\n\n", pc.YELLOW)
     27 + pc.printout("Version 1.1 - Developed by Giuseppe Criscione\n\n", pc.YELLOW)
    26 28   pc.printout("Type 'list' to show all allowed commands\n")
    27 29   pc.printout("Type 'FILE=y' to save results to files like '<target username>_<command>.txt (deafult is disabled)'\n")
    28 30   pc.printout("Type 'FILE=n' to disable saving to files'\n")
    skipped 21 lines
    50 52   print("Get email of target followers")
    51 53   pc.printout("fwingsemail\t")
    52 54   print("Get email of users followed by target")
     55 + pc.printout("fwersnumber\t")
     56 + print("Get phone number of target followers")
     57 + pc.printout("fwingsnumber\t")
     58 + print("Get phone number of users followed by target")
    53 59   pc.printout("hashtags\t")
    54 60   print("Get hashtags used by target")
    55 61   pc.printout("info\t\t")
    skipped 32 lines
    88 94   else:
    89 95   return None
    90 96   
     97 +def _quit():
     98 + pc.printout("Goodbye!\n", pc.RED)
     99 + sys.exit(0)
     100 + 
    91 101   
    92 102  signal.signal(signal.SIGINT, signal_handler)
    93  -readline.parse_and_bind("tab: complete")
    94  -readline.set_completer(completer)
     103 +if is_windows:
     104 + pyreadline.Readline().parse_and_bind("tab: complete")
     105 + pyreadline.Readline().set_completer(completer)
     106 +else:
     107 + gnureadline.parse_and_bind("tab: complete")
     108 + gnureadline.set_completer(completer)
    95 109   
    96 110  printlogo()
    97 111   
    skipped 8 lines
    106 120   
    107 121  api = Osintgram(args.id, args.file, args.json)
    108 122   
     123 + 
     124 +commands = {
     125 + 'list': cmdlist,
     126 + 'help': cmdlist,
     127 + 'quit': _quit,
     128 + 'exit': _quit,
     129 + 'addrs': api.get_addrs,
     130 + 'captions': api.get_captions,
     131 + 'comments': api.get_total_comments,
     132 + 'followers': api.get_followers,
     133 + 'followings': api.get_followings,
     134 + 'fwersemail': api.get_fwersemail,
     135 + 'fwingsemail': api.get_fwingsemail,
     136 + 'fwersnumber': api.get_fwersnumber,
     137 + 'fwingsnumber': api.get_fwingsnumber,
     138 + 'hashtags': api.get_hashtags,
     139 + 'info': api.get_user_info,
     140 + 'likes': api.get_total_likes,
     141 + 'mediatype': api.get_media_type,
     142 + 'photodes': api.get_photo_description,
     143 + 'photos': api.get_user_photo,
     144 + 'propic': api.get_user_propic,
     145 + 'stories': api.get_user_stories,
     146 + 'tagged': api.get_people_tagged_by_user,
     147 + 'target': api.change_target,
     148 + 'wcommented': api.get_people_who_commented,
     149 + 'wtagged': api.get_people_who_tagged
     150 +}
     151 + 
     152 +signal.signal(signal.SIGINT, signal_handler)
     153 +gnureadline.parse_and_bind("tab: complete")
     154 +gnureadline.set_completer(completer)
     155 + 
    109 156  while True:
    110 157   pc.printout("Run a command: ", pc.YELLOW)
    111 158   cmd = input()
    112  - if cmd == "quit" or cmd == "exit":
    113  - pc.printout("Goodbye!\n", pc.RED)
    114  - sys.exit(0)
    115  - elif cmd == "list" or cmd == "help":
    116  - cmdlist()
    117  - elif cmd == "addrs":
    118  - api.get_addrs()
    119  - elif cmd == "captions":
    120  - api.get_captions()
    121  - elif cmd == "comments":
    122  - api.get_total_comments()
    123  - elif cmd == "followers":
    124  - api.get_followers()
    125  - elif cmd == "followings":
    126  - api.get_followings()
    127  - elif cmd == 'fwersemail':
    128  - api.get_fwersemail()
    129  - elif cmd == 'fwingsemail':
    130  - api.get_fwingsemail()
    131  - elif cmd == "hashtags":
    132  - api.get_hashtags()
    133  - elif cmd == "info":
    134  - api.get_user_info()
    135  - elif cmd == "likes":
    136  - api.get_total_likes()
    137  - elif cmd == "mediatype":
    138  - api.get_media_type()
    139  - elif cmd == "photodes":
    140  - api.get_photo_description()
    141  - elif cmd == "photos":
    142  - api.get_user_photo()
    143  - elif cmd == "propic":
    144  - api.get_user_propic()
    145  - elif cmd == "stories":
    146  - api.get_user_stories()
    147  - elif cmd == "tagged":
    148  - api.get_people_tagged_by_user()
    149  - elif cmd == "target":
    150  - api.change_target()
    151  - elif cmd == "wcommented":
    152  - api.get_people_who_commented()
    153  - elif cmd == "wtagged":
    154  - api.get_people_who_tagged()
     159 + 
     160 + _cmd = commands.get(cmd)
     161 +
     162 + if _cmd:
     163 + _cmd()
    155 164   elif cmd == "FILE=y":
    156 165   api.set_write_file(True)
    157 166   elif cmd == "FILE=n":
    skipped 2 lines
    160 169   api.set_json_dump(True)
    161 170   elif cmd == "JSON=n":
    162 171   api.set_json_dump(False)
     172 + elif cmd == "":
     173 + print("")
    163 174   else:
    164 175   pc.printout("Unknown command\n", pc.RED)
    165 176   
  • ■ ■ ■ ■ ■
    requirements.txt
    skipped 2 lines
    3 3  geopy>=2.0.0
    4 4  prettytable==0.7.2
    5 5  instagram-private-api==1.6.0
    6  -readline>=6.2.4
     6 +gnureadline>=8.0.0; platform_system != "Windows"
     7 +pyreadline==2.1; platform_system == "Windows"
    7 8   
  • ■ ■ ■ ■ ■
    src/Osintgram.py
    skipped 8 lines
    9 9   
    10 10  from geopy.geocoders import Nominatim
    11 11  from instagram_private_api import Client as AppClient
    12  -from instagram_private_api import ClientCookieExpiredError, ClientLoginRequiredError, ClientError
     12 +from instagram_private_api import ClientCookieExpiredError, ClientLoginRequiredError, ClientError, ClientThrottledError
    13 13   
    14 14  from prettytable import PrettyTable
    15 15   
    skipped 262 lines
    278 278   
    279 279   pc.printout("Searching for target followers...\n")
    280 280   
     281 + _followers = []
    281 282   followers = []
     283 + 
    282 284   
    283 285   rank_token = AppClient.generate_uuid()
    284 286   data = self.api.user_followers(str(self.target_id), rank_token=rank_token)
    285 287   
    286  - for user in data['users']:
     288 + _followers.extend(data.get('users', []))
     289 + 
     290 + next_max_id = data.get('next_max_id')
     291 + while next_max_id:
     292 + sys.stdout.write("\rCatched %i followers" % len(_followers))
     293 + sys.stdout.flush()
     294 + results = self.api.user_followers(str(self.target_id), rank_token=rank_token, max_id=next_max_id)
     295 + _followers.extend(results.get('users', []))
     296 + next_max_id = results.get('next_max_id')
     297 + 
     298 + print("\n")
     299 +
     300 + for user in _followers:
    287 301   u = {
    288 302   'id': user['pk'],
    289 303   'username': user['username'],
    skipped 40 lines
    330 344   
    331 345   pc.printout("Searching for target followings...\n")
    332 346   
     347 + _followings = []
    333 348   followings = []
    334 349   
    335 350   rank_token = AppClient.generate_uuid()
    336 351   data = self.api.user_following(str(self.target_id), rank_token=rank_token)
    337 352   
    338  - for user in data['users']:
     353 + _followings.extend(data.get('users', []))
     354 + 
     355 + next_max_id = data.get('next_max_id')
     356 + while next_max_id:
     357 + sys.stdout.write("\rCatched %i followings" % len(_followings))
     358 + sys.stdout.flush()
     359 + results = self.api.user_following(str(self.target_id), rank_token=rank_token, max_id=next_max_id)
     360 + _followings.extend(results.get('users', []))
     361 + next_max_id = results.get('next_max_id')
     362 + 
     363 + print("\n")
     364 + 
     365 + for user in _followings:
    339 366   u = {
    340 367   'id': user['pk'],
    341 368   'username': user['username'],
    skipped 101 lines
    443 470   
    444 471   def get_user_info(self):
    445 472   try:
    446  - endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target})
     473 + endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target_id})
    447 474   content = self.api._call_api(endpoint)
    448 475  
    449 476   data = content['user_detail']['user']
    skipped 66 lines
    516 543   json.dump(user, f)
    517 544   
    518 545   except ClientError as e:
     546 + print(e)
    519 547   pc.printout("Oops... " + str(self.target) + " non exist, please enter a valid username.", pc.RED)
    520 548   pc.printout("\n")
    521 549   exit(2)
    skipped 324 lines
    846 874   def get_user_propic(self):
    847 875   
    848 876   try:
    849  - endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target})
     877 + endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target_id})
    850 878   content = self.api._call_api(endpoint)
    851 879   
    852 880   data = content['user_detail']['user']
    skipped 14 lines
    867 895   pc.printout("Sorry! No results found :-(\n", pc.RED)
    868 896  
    869 897   except ClientError as e:
    870  - print(e)
    871  - print("An error occured... exit")
     898 + error = json.loads(e.error_response)
     899 + print(error['message'])
     900 + print(error['error_title'])
    872 901   exit(2)
    873 902   
    874 903   def get_user_stories(self):
    skipped 100 lines
    975 1004   
    976 1005   def get_user(self, username):
    977 1006   try:
    978  - endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target})
    979  - content = self.api._call_api(endpoint)
    980  - 
     1007 + content = self.api.username_info(username)
    981 1008   if self.writeFile:
    982 1009   file_name = "output/" + self.target + "_user_id.txt"
    983 1010   file = open(file_name, "w")
    984  - file.write(str(content['user_detail']['user']['pk']))
     1011 + file.write(str(content['user']['pk']))
    985 1012   file.close()
    986 1013   
    987 1014   user = dict()
    988  - user['id'] = content['user_detail']['user']['pk']
    989  - user['is_private'] = content['user_detail']['user']['is_private']
     1015 + user['id'] = content['user']['pk']
     1016 + user['is_private'] = content['user']['is_private']
    990 1017   
    991 1018   return user
    992 1019   except ClientError as e:
    993  - pc.printout("Oops... " + str(self.target) + " non exist, please enter a valid username.", pc.RED)
    994  - pc.printout("\n")
    995  - exit(2)
    996  - 
     1020 + error = json.loads(e.error_response)
     1021 + if 'message' in error:
     1022 + print(error['message'])
     1023 + if 'error_title' in error:
     1024 + print(error['error_title'])
     1025 + if 'challenge' in error:
     1026 + print("Please follow this link to complete the challenge: " + error['challenge']['url'])
     1027 + sys.exit(2)
    997 1028  
    998 1029   
    999 1030   def set_write_file(self, flag):
    skipped 99 lines
    1099 1130   if self.check_private_profile():
    1100 1131   return
    1101 1132   
    1102  - pc.printout("Searching for emails of target followers... this can take a few minutes\n")
     1133 + followers = []
    1103 1134  
    1104  - followers = []
     1135 + try:
    1105 1136   
    1106  - rank_token = AppClient.generate_uuid()
    1107  - data = self.api.user_followers(str(self.target_id), rank_token=rank_token)
     1137 + pc.printout("Searching for emails of target followers... this can take a few minutes\n")
     1138 + 
     1139 + rank_token = AppClient.generate_uuid()
     1140 + data = self.api.user_followers(str(self.target_id), rank_token=rank_token)
     1141 + 
     1142 + for user in data.get('users', []):
     1143 + u = {
     1144 + 'id': user['pk'],
     1145 + 'username': user['username'],
     1146 + 'full_name': user['full_name']
     1147 + }
     1148 + followers.append(u)
    1108 1149   
    1109  - for user in data['users']:
    1110  - u = {
    1111  - 'id': user['pk'],
    1112  - 'username': user['username'],
    1113  - 'full_name': user['full_name']
    1114  - }
    1115  - followers.append(u)
     1150 + next_max_id = data.get('next_max_id')
     1151 + while next_max_id:
     1152 + sys.stdout.write("\rCatched %i followers email" % len(followers))
     1153 + sys.stdout.flush()
     1154 + results = self.api.user_followers(str(self.target_id), rank_token=rank_token, max_id=next_max_id)
     1155 +
     1156 + for user in results.get('users', []):
     1157 + u = {
     1158 + 'id': user['pk'],
     1159 + 'username': user['username'],
     1160 + 'full_name': user['full_name']
     1161 + }
     1162 + followers.append(u)
     1163 + 
     1164 + next_max_id = results.get('next_max_id')
     1165 +
     1166 + print("\n")
     1167 + 
     1168 + results = []
    1116 1169   
    1117  - results = []
     1170 + for follow in followers:
     1171 + user = self.api.user_info(str(follow['id']))
     1172 + if 'public_email' in user['user'] and user['user']['public_email']:
     1173 + follow['email'] = user['user']['public_email']
     1174 + results.append(follow)
    1118 1175   
    1119  - for follow in followers:
    1120  - user = self.api.user_info(str(follow['id']))
    1121  - if 'public_email' in user['user']:
    1122  - follow['email'] = user['user']['public_email']
    1123  - results.append(follow)
     1176 + except ClientThrottledError as e:
     1177 + pc.printout("\nError: Instagram blocked the requests. Please wait a few minutes before you try again.", pc.RED)
     1178 + pc.printout("\n")
     1179 + return
    1124 1180   
    1125 1181   if len(results) > 0:
    1126 1182   
    skipped 28 lines
    1155 1211   if self.check_private_profile():
    1156 1212   return
    1157 1213   
    1158  - pc.printout("Searching for emails of users followed by target... this can take a few minutes\n")
    1159  - 
    1160 1214   followings = []
    1161 1215   
    1162  - rank_token = AppClient.generate_uuid()
    1163  - data = self.api.user_following(str(self.target_id), rank_token=rank_token)
     1216 + try:
    1164 1217   
    1165  - for user in data['users']:
    1166  - u = {
    1167  - 'id': user['pk'],
    1168  - 'username': user['username'],
    1169  - 'full_name': user['full_name']
    1170  - }
    1171  - followings.append(u)
     1218 + pc.printout("Searching for emails of users followed by target... this can take a few minutes\n")
    1172 1219   
    1173  - results = []
     1220 + rank_token = AppClient.generate_uuid()
     1221 + data = self.api.user_following(str(self.target_id), rank_token=rank_token)
    1174 1222   
    1175  - for follow in followings:
    1176  - user = self.api.user_info(str(follow['id']))
    1177  - if 'public_email' in user['user']:
    1178  - follow['email'] = user['user']['public_email']
    1179  - results.append(follow)
     1223 + for user in data.get('users', []):
     1224 + u = {
     1225 + 'id': user['pk'],
     1226 + 'username': user['username'],
     1227 + 'full_name': user['full_name']
     1228 + }
     1229 + followings.append(u)
    1180 1230   
    1181  - if len(results) > 0:
     1231 + next_max_id = data.get('next_max_id')
    1182 1232  
     1233 + while next_max_id:
     1234 + results = self.api.user_following(str(self.target_id), rank_token=rank_token, max_id=next_max_id)
     1235 + 
     1236 + for user in results.get('users', []):
     1237 + u = {
     1238 + 'id': user['pk'],
     1239 + 'username': user['username'],
     1240 + 'full_name': user['full_name']
     1241 + }
     1242 + followings.append(u)
     1243 + 
     1244 + next_max_id = results.get('next_max_id')
     1245 +
     1246 + results = []
     1247 + 
     1248 + for follow in followings:
     1249 + sys.stdout.write("\rCatched %i followings email" % len(results))
     1250 + sys.stdout.flush()
     1251 + user = self.api.user_info(str(follow['id']))
     1252 + if 'public_email' in user['user'] and user['user']['public_email']:
     1253 + follow['email'] = user['user']['public_email']
     1254 + results.append(follow)
     1255 +
     1256 + except ClientThrottledError as e:
     1257 + pc.printout("\nError: Instagram blocked the requests. Please wait a few minutes before you try again.", pc.RED)
     1258 + pc.printout("\n")
     1259 + return
     1260 +
     1261 + print("\n")
     1262 + 
     1263 + if len(results) > 0:
    1183 1264   t = PrettyTable(['ID', 'Username', 'Full Name', 'Email'])
    1184 1265   t.align["ID"] = "l"
    1185 1266   t.align["Username"] = "l"
    skipped 21 lines
    1207 1288   else:
    1208 1289   pc.printout("Sorry! No results found :-(\n", pc.RED)
    1209 1290   
     1291 + def get_fwingsnumber(self):
     1292 + if self.check_private_profile():
     1293 + return
     1294 + 
     1295 + results = []
     1296 +
     1297 + try:
     1298 + 
     1299 + pc.printout("Searching for phone numbers of users followed by target... this can take a few minutes\n")
     1300 + 
     1301 + followings = []
     1302 + 
     1303 + rank_token = AppClient.generate_uuid()
     1304 + data = self.api.user_following(str(self.target_id), rank_token=rank_token)
     1305 + 
     1306 + for user in data.get('users', []):
     1307 + u = {
     1308 + 'id': user['pk'],
     1309 + 'username': user['username'],
     1310 + 'full_name': user['full_name']
     1311 + }
     1312 + followings.append(u)
     1313 + 
     1314 + next_max_id = data.get('next_max_id')
     1315 +
     1316 + while next_max_id:
     1317 + results = self.api.user_following(str(self.target_id), rank_token=rank_token, max_id=next_max_id)
     1318 + 
     1319 + for user in results.get('users', []):
     1320 + u = {
     1321 + 'id': user['pk'],
     1322 + 'username': user['username'],
     1323 + 'full_name': user['full_name']
     1324 + }
     1325 + followings.append(u)
     1326 + 
     1327 + next_max_id = results.get('next_max_id')
     1328 +
     1329 + 
     1330 + for follow in followings:
     1331 + sys.stdout.write("\rCatched %i followings phone numbers" % len(results))
     1332 + sys.stdout.flush()
     1333 + user = self.api.user_info(str(follow['id']))
     1334 + if 'contact_phone_number' in user['user'] and user['user']['contact_phone_number']:
     1335 + follow['contact_phone_number'] = user['user']['contact_phone_number']
     1336 + results.append(follow)
     1337 + 
     1338 + except ClientThrottledError as e:
     1339 + pc.printout("\nError: Instagram blocked the requests. Please wait a few minutes before you try again.", pc.RED)
     1340 + pc.printout("\n")
     1341 + return
     1342 +
     1343 + print("\n")
     1344 + 
     1345 + if len(results) > 0:
     1346 + t = PrettyTable(['ID', 'Username', 'Full Name', 'Phone'])
     1347 + t.align["ID"] = "l"
     1348 + t.align["Username"] = "l"
     1349 + t.align["Full Name"] = "l"
     1350 + t.align["Phone number"] = "l"
     1351 + 
     1352 + json_data = {}
     1353 + 
     1354 + for node in results:
     1355 + t.add_row([str(node['id']), node['username'], node['full_name'], node['contact_phone_number']])
     1356 + 
     1357 + if self.writeFile:
     1358 + file_name = "output/" + self.target + "_fwingsnumber.txt"
     1359 + file = open(file_name, "w")
     1360 + file.write(str(t))
     1361 + file.close()
     1362 + 
     1363 + if self.jsonDump:
     1364 + json_data['followings_phone_numbers'] = results
     1365 + json_file_name = "output/" + self.target + "_fwingsnumber.json"
     1366 + with open(json_file_name, 'w') as f:
     1367 + json.dump(json_data, f)
     1368 + 
     1369 + print(t)
     1370 + else:
     1371 + pc.printout("Sorry! No results found :-(\n", pc.RED)
     1372 + 
     1373 + def get_fwersnumber(self):
     1374 + if self.check_private_profile():
     1375 + return
     1376 + 
     1377 + followings = []
     1378 + 
     1379 + try:
     1380 + 
     1381 + pc.printout("Searching for phone numbers of users followers... this can take a few minutes\n")
     1382 + 
     1383 + 
     1384 + rank_token = AppClient.generate_uuid()
     1385 + data = self.api.user_following(str(self.target_id), rank_token=rank_token)
     1386 + 
     1387 + for user in data.get('users', []):
     1388 + u = {
     1389 + 'id': user['pk'],
     1390 + 'username': user['username'],
     1391 + 'full_name': user['full_name']
     1392 + }
     1393 + followings.append(u)
     1394 + 
     1395 + next_max_id = data.get('next_max_id')
     1396 +
     1397 + while next_max_id:
     1398 + results = self.api.user_following(str(self.target_id), rank_token=rank_token, max_id=next_max_id)
     1399 + 
     1400 + for user in results.get('users', []):
     1401 + u = {
     1402 + 'id': user['pk'],
     1403 + 'username': user['username'],
     1404 + 'full_name': user['full_name']
     1405 + }
     1406 + followings.append(u)
     1407 + 
     1408 + next_max_id = results.get('next_max_id')
     1409 +
     1410 + results = []
     1411 + 
     1412 + for follow in followings:
     1413 + sys.stdout.write("\rCatched %i followers phone numbers" % len(results))
     1414 + sys.stdout.flush()
     1415 + user = self.api.user_info(str(follow['id']))
     1416 + if 'contact_phone_number' in user['user'] and user['user']['contact_phone_number']:
     1417 + follow['contact_phone_number'] = user['user']['contact_phone_number']
     1418 + results.append(follow)
     1419 + 
     1420 + except ClientThrottledError as e:
     1421 + pc.printout("\nError: Instagram blocked the requests. Please wait a few minutes before you try again.", pc.RED)
     1422 + pc.printout("\n")
     1423 + return
     1424 + 
     1425 + print("\n")
     1426 + 
     1427 + if len(results) > 0:
     1428 + t = PrettyTable(['ID', 'Username', 'Full Name', 'Phone'])
     1429 + t.align["ID"] = "l"
     1430 + t.align["Username"] = "l"
     1431 + t.align["Full Name"] = "l"
     1432 + t.align["Phone number"] = "l"
     1433 + 
     1434 + json_data = {}
     1435 + 
     1436 + for node in results:
     1437 + t.add_row([str(node['id']), node['username'], node['full_name'], node['contact_phone_number']])
     1438 + 
     1439 + if self.writeFile:
     1440 + file_name = "output/" + self.target + "_fwersnumber.txt"
     1441 + file = open(file_name, "w")
     1442 + file.write(str(t))
     1443 + file.close()
     1444 + 
     1445 + if self.jsonDump:
     1446 + json_data['followings_phone_numbers'] = results
     1447 + json_file_name = "output/" + self.target + "_fwerssnumber.json"
     1448 + with open(json_file_name, 'w') as f:
     1449 + json.dump(json_data, f)
     1450 + 
     1451 + print(t)
     1452 + else:
     1453 + pc.printout("Sorry! No results found :-(\n", pc.RED)
     1454 + 
     1455 + def get_comments(self):
     1456 + if self.check_private_profile():
     1457 + return
     1458 + 
     1459 + pc.printout("Searching for users who commented...\n")
     1460 + 
     1461 + data = self.__get_feed__()
     1462 + users = []
     1463 + 
     1464 + for post in data:
     1465 + comments = self.__get_comments__(post['id'])
     1466 + for comment in comments:
     1467 + print(comment['text'])
     1468 +
     1469 + # if not any(u['id'] == comment['user']['pk'] for u in users):
     1470 + # user = {
     1471 + # 'id': comment['user']['pk'],
     1472 + # 'username': comment['user']['username'],
     1473 + # 'full_name': comment['user']['full_name'],
     1474 + # 'counter': 1
     1475 + # }
     1476 + # users.append(user)
     1477 + # else:
     1478 + # for user in users:
     1479 + # if user['id'] == comment['user']['pk']:
     1480 + # user['counter'] += 1
     1481 + # break
     1482 + 
     1483 + if len(users) > 0:
     1484 + ssort = sorted(users, key=lambda value: value['counter'], reverse=True)
     1485 + 
     1486 + json_data = {}
     1487 + 
     1488 + t = PrettyTable()
     1489 + 
     1490 + t.field_names = ['Comments', 'ID', 'Username', 'Full Name']
     1491 + t.align["Comments"] = "l"
     1492 + t.align["ID"] = "l"
     1493 + t.align["Username"] = "l"
     1494 + t.align["Full Name"] = "l"
     1495 + 
     1496 + for u in ssort:
     1497 + t.add_row([str(u['counter']), u['id'], u['username'], u['full_name']])
     1498 + 
     1499 + print(t)
     1500 + 
     1501 + if self.writeFile:
     1502 + file_name = "output/" + self.target + "_users_who_commented.txt"
     1503 + file = open(file_name, "w")
     1504 + file.write(str(t))
     1505 + file.close()
     1506 + 
     1507 + if self.jsonDump:
     1508 + json_data['users_who_commented'] = ssort
     1509 + json_file_name = "output/" + self.target + "_users_who_commented.json"
     1510 + with open(json_file_name, 'w') as f:
     1511 + json.dump(json_data, f)
     1512 + else:
     1513 + pc.printout("Sorry! No results found :-(\n", pc.RED)
     1514 + 
Please wait...
Page is in error, reload to recover