| 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 | + | |