| skipped 54 lines |
55 | 55 | | def setTarget(self, target, show_output): |
56 | 56 | | self.target = target |
57 | 57 | | user = self.get_user(target) |
58 | | - | self.target_id = user['id'] |
59 | | - | self.is_private = user['is_private'] |
60 | | - | self.following = self.check_following() |
61 | | - | if(show_output): |
62 | | - | self.__printTargetBanner__() |
| 58 | + | if user: |
| 59 | + | self.target_id = user['id'] |
| 60 | + | self.is_private = user['is_private'] |
| 61 | + | self.following = self.check_following() |
| 62 | + | if(show_output): |
| 63 | + | self.__printTargetBanner__() |
| 64 | + | return True |
| 65 | + | else: |
| 66 | + | return False |
63 | 67 | | |
64 | 68 | | def get_api(self): |
65 | 69 | | return self.api |
| skipped 4 lines |
70 | 74 | | def generate_uuid(self): |
71 | 75 | | return AppClient.generate_uuid() |
72 | 76 | | |
73 | | - | def __get_feed__(self): |
74 | | - | data = [] |
75 | | - | |
76 | | - | result = self.api.user_feed(str(self.target_id)) |
77 | | - | data.extend(result.get('items', [])) |
78 | | - | |
79 | | - | next_max_id = result.get('next_max_id') |
80 | | - | while next_max_id: |
81 | | - | results = self.api.user_feed(str(self.target_id), max_id=next_max_id) |
82 | | - | data.extend(results.get('items', [])) |
83 | | - | next_max_id = results.get('next_max_id') |
84 | | - | |
85 | | - | return data |
86 | | - | |
87 | | - | def __get_comments__(self, media_id): |
88 | | - | comments = [] |
89 | | - | |
90 | | - | result = self.api.media_comments(str(media_id)) |
91 | | - | comments.extend(result.get('comments', [])) |
92 | | - | |
93 | | - | next_max_id = result.get('next_max_id') |
94 | | - | while next_max_id: |
95 | | - | results = self.api.media_comments(str(media_id), max_id=next_max_id) |
96 | | - | comments.extend(results.get('comments', [])) |
97 | | - | next_max_id = results.get('next_max_id') |
98 | | - | |
99 | | - | return comments |
100 | | - | |
101 | 77 | | def __printTargetBanner__(self): |
102 | 78 | | pc.printout("\nLogged as ", pc.GREEN) |
103 | 79 | | pc.printout(self.api.username, pc.CYAN) |
| skipped 9 lines |
113 | 89 | | |
114 | 90 | | print('\n') |
115 | 91 | | |
116 | | - | def change_target(self): |
117 | | - | pc.printout("Insert new target username: ", pc.YELLOW) |
118 | | - | line = input() |
119 | | - | self.setTarget(line, True) |
120 | | - | return |
121 | | - | |
122 | | - | def get_addrs(self): |
123 | | - | if self.check_private_profile(): |
124 | | - | return |
125 | | - | |
126 | | - | pc.printout("Searching for " + self.target + " localizations...\n") |
127 | | - | |
128 | | - | data = self.__get_feed__() |
129 | | - | |
130 | | - | locations = {} |
131 | | - | |
132 | | - | for post in data: |
133 | | - | if 'location' in post and post['location'] is not None: |
134 | | - | if 'lat' in post['location'] and 'lng' in post['location']: |
135 | | - | lat = post['location']['lat'] |
136 | | - | lng = post['location']['lng'] |
137 | | - | locations[str(lat) + ', ' + str(lng)] = post.get('taken_at') |
138 | | - | |
139 | | - | address = {} |
140 | | - | for k, v in locations.items(): |
141 | | - | details = self.geolocator.reverse(k) |
142 | | - | unix_timestamp = datetime.datetime.fromtimestamp(v) |
143 | | - | address[details.address] = unix_timestamp.strftime('%Y-%m-%d %H:%M:%S') |
144 | | - | |
145 | | - | sort_addresses = sorted(address.items(), key=lambda p: p[1], reverse=True) |
146 | | - | |
147 | | - | if len(sort_addresses) > 0: |
148 | | - | t = PrettyTable() |
149 | | - | |
150 | | - | t.field_names = ['Post', 'Address', 'time'] |
151 | | - | t.align["Post"] = "l" |
152 | | - | t.align["Address"] = "l" |
153 | | - | t.align["Time"] = "l" |
154 | | - | pc.printout("\nWoohoo! We found " + str(len(sort_addresses)) + " addresses\n", pc.GREEN) |
155 | | - | |
156 | | - | i = 1 |
157 | | - | |
158 | | - | json_data = {} |
159 | | - | addrs_list = [] |
160 | | - | |
161 | | - | for address, time in sort_addresses: |
162 | | - | t.add_row([str(i), address, time]) |
163 | | - | |
164 | | - | if self.jsonDump: |
165 | | - | addr = { |
166 | | - | 'address': address, |
167 | | - | 'time': time |
168 | | - | } |
169 | | - | addrs_list.append(addr) |
170 | | - | |
171 | | - | i = i + 1 |
172 | | - | |
173 | | - | if self.writeFile: |
174 | | - | file_name = self.output_dir + "/" + self.target + "_addrs.txt" |
175 | | - | file = open(file_name, "w") |
176 | | - | file.write(str(t)) |
177 | | - | file.close() |
178 | | - | |
179 | | - | if self.jsonDump: |
180 | | - | json_data['address'] = addrs_list |
181 | | - | json_file_name = self.output_dir + "/" + self.target + "_addrs.json" |
182 | | - | with open(json_file_name, 'w') as f: |
183 | | - | json.dump(json_data, f) |
184 | | - | |
185 | | - | print(t) |
186 | | - | else: |
187 | | - | pc.printout("Sorry! No results found :-(\n", pc.RED) |
188 | | - | |
189 | | - | def get_captions(self): |
190 | | - | if self.check_private_profile(): |
191 | | - | return |
192 | | - | |
193 | | - | pc.printout("Searching for " + self.target + " captions...\n") |
194 | | - | |
195 | | - | captions = [] |
196 | | - | |
197 | | - | data = self.__get_feed__() |
198 | | - | counter = 0 |
199 | | - | |
200 | | - | try: |
201 | | - | for item in data: |
202 | | - | if "caption" in item: |
203 | | - | if item["caption"] is not None: |
204 | | - | text = item["caption"]["text"] |
205 | | - | captions.append(text) |
206 | | - | counter = counter + 1 |
207 | | - | sys.stdout.write("\rFound %i" % counter) |
208 | | - | sys.stdout.flush() |
209 | | - | |
210 | | - | except AttributeError: |
211 | | - | pass |
212 | | - | |
213 | | - | except KeyError: |
214 | | - | pass |
215 | | - | |
216 | | - | json_data = {} |
217 | | - | |
218 | | - | if counter > 0: |
219 | | - | pc.printout("\nWoohoo! We found " + str(counter) + " captions\n", pc.GREEN) |
220 | | - | |
221 | | - | file = None |
222 | | - | |
223 | | - | if self.writeFile: |
224 | | - | file_name = self.output_dir + "/" + self.target + "_captions.txt" |
225 | | - | file = open(file_name, "w") |
226 | | - | |
227 | | - | for s in captions: |
228 | | - | print(s + "\n") |
229 | | - | |
230 | | - | if self.writeFile: |
231 | | - | file.write(s + "\n") |
232 | | - | |
233 | | - | if self.jsonDump: |
234 | | - | json_data['captions'] = captions |
235 | | - | json_file_name = self.output_dir + "/" + self.target + "_followings.json" |
236 | | - | with open(json_file_name, 'w') as f: |
237 | | - | json.dump(json_data, f) |
238 | | - | |
239 | | - | if file is not None: |
240 | | - | file.close() |
241 | | - | |
242 | | - | else: |
243 | | - | pc.printout("Sorry! No results found :-(\n", pc.RED) |
244 | | - | |
245 | | - | return |
246 | | - | |
247 | | - | def get_total_comments(self): |
248 | | - | if self.check_private_profile(): |
249 | | - | return |
250 | | - | |
251 | | - | pc.printout("Searching for " + self.target + " total comments...\n") |
252 | | - | |
253 | | - | comments_counter = 0 |
254 | | - | posts = 0 |
255 | | - | |
256 | | - | data = self.__get_feed__() |
257 | | - | |
258 | | - | for post in data: |
259 | | - | comments_counter += post['comment_count'] |
260 | | - | posts += 1 |
261 | | - | |
262 | | - | if self.writeFile: |
263 | | - | file_name = self.output_dir + "/" + self.target + "_comments.txt" |
264 | | - | file = open(file_name, "w") |
265 | | - | file.write(str(comments_counter) + " comments in " + str(posts) + " posts\n") |
266 | | - | file.close() |
267 | | - | |
268 | | - | if self.jsonDump: |
269 | | - | json_data = { |
270 | | - | 'comment_counter': comments_counter, |
271 | | - | 'posts': posts |
272 | | - | } |
273 | | - | json_file_name = self.output_dir + "/" + self.target + "_comments.json" |
274 | | - | with open(json_file_name, 'w') as f: |
275 | | - | json.dump(json_data, f) |
276 | | - | |
277 | | - | pc.printout(str(comments_counter), pc.MAGENTA) |
278 | | - | pc.printout(" comments in " + str(posts) + " posts\n") |
279 | | - | |
280 | | - | def get_comment_data(self): |
281 | | - | if self.check_private_profile(): |
282 | | - | return |
283 | | - | |
284 | | - | pc.printout("Retrieving all comments, this may take a moment...\n") |
285 | | - | data = self.__get_feed__() |
286 | | - | |
287 | | - | _comments = [] |
288 | | - | t = PrettyTable(['POST ID', 'ID', 'Username', 'Comment']) |
289 | | - | t.align["POST ID"] = "l" |
290 | | - | t.align["ID"] = "l" |
291 | | - | t.align["Username"] = "l" |
292 | | - | t.align["Comment"] = "l" |
293 | | - | |
294 | | - | for post in data: |
295 | | - | post_id = post.get('id') |
296 | | - | comments = self.api.media_n_comments(post_id) |
297 | | - | for comment in comments: |
298 | | - | t.add_row([post_id, comment.get('user_id'), comment.get('user').get('username'), comment.get('text')]) |
299 | | - | comment = { |
300 | | - | "post_id": post_id, |
301 | | - | "user_id":comment.get('user_id'), |
302 | | - | "username": comment.get('user').get('username'), |
303 | | - | "comment": comment.get('text') |
304 | | - | } |
305 | | - | _comments.append(comment) |
306 | | - | |
307 | | - | print(t) |
308 | | - | if self.writeFile: |
309 | | - | file_name = self.output_dir + "/" + self.target + "_comment_data.txt" |
310 | | - | with open(file_name, 'w') as f: |
311 | | - | f.write(str(t)) |
312 | | - | f.close() |
313 | | - | |
314 | | - | if self.jsonDump: |
315 | | - | file_name_json = self.output_dir + "/" + self.target + "_comment_data.json" |
316 | | - | with open(file_name_json, 'w') as f: |
317 | | - | f.write("{ \"Comments\":[ \n") |
318 | | - | f.write('\n'.join(json.dumps(comment) for comment in _comments) + ',\n') |
319 | | - | f.write("]} ") |
320 | | - | |
321 | | - | def get_user_info(self): |
322 | | - | try: |
323 | | - | endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target_id}) |
324 | | - | content = self.api._call_api(endpoint) |
325 | | - | |
326 | | - | data = content['user_detail']['user'] |
327 | | - | |
328 | | - | pc.printout("[ID] ", pc.GREEN) |
329 | | - | pc.printout(str(data['pk']) + '\n') |
330 | | - | pc.printout("[FULL NAME] ", pc.RED) |
331 | | - | pc.printout(str(data['full_name']) + '\n') |
332 | | - | pc.printout("[BIOGRAPHY] ", pc.CYAN) |
333 | | - | pc.printout(str(data['biography']) + '\n') |
334 | | - | pc.printout("[FOLLOWED] ", pc.BLUE) |
335 | | - | pc.printout(str(data['follower_count']) + '\n') |
336 | | - | pc.printout("[FOLLOW] ", pc.GREEN) |
337 | | - | pc.printout(str(data['following_count']) + '\n') |
338 | | - | pc.printout("[BUSINESS ACCOUNT] ", pc.RED) |
339 | | - | pc.printout(str(data['is_business']) + '\n') |
340 | | - | if data['is_business']: |
341 | | - | if not data['can_hide_category']: |
342 | | - | pc.printout("[BUSINESS CATEGORY] ") |
343 | | - | pc.printout(str(data['category']) + '\n') |
344 | | - | pc.printout("[VERIFIED ACCOUNT] ", pc.CYAN) |
345 | | - | pc.printout(str(data['is_verified']) + '\n') |
346 | | - | if 'public_email' in data and data['public_email']: |
347 | | - | pc.printout("[EMAIL] ", pc.BLUE) |
348 | | - | pc.printout(str(data['public_email']) + '\n') |
349 | | - | pc.printout("[HD PROFILE PIC] ", pc.GREEN) |
350 | | - | pc.printout(str(data['hd_profile_pic_url_info']['url']) + '\n') |
351 | | - | if 'fb_page_call_to_action_id' in data and data['fb_page_call_to_action_id']: |
352 | | - | pc.printout("[FB PAGE] ", pc.RED) |
353 | | - | pc.printout(str(data['connected_fb_page']) + '\n') |
354 | | - | if 'whatsapp_number' in data and data['whatsapp_number']: |
355 | | - | pc.printout("[WHATSAPP NUMBER] ", pc.GREEN) |
356 | | - | pc.printout(str(data['whatsapp_number']) + '\n') |
357 | | - | if 'city_name' in data and data['city_name']: |
358 | | - | pc.printout("[CITY] ", pc.YELLOW) |
359 | | - | pc.printout(str(data['city_name']) + '\n') |
360 | | - | if 'address_street' in data and data['address_street']: |
361 | | - | pc.printout("[ADDRESS STREET] ", pc.RED) |
362 | | - | pc.printout(str(data['address_street']) + '\n') |
363 | | - | if 'contact_phone_number' in data and data['contact_phone_number']: |
364 | | - | pc.printout("[CONTACT PHONE NUMBER] ", pc.CYAN) |
365 | | - | pc.printout(str(data['contact_phone_number']) + '\n') |
366 | | - | |
367 | | - | if self.jsonDump: |
368 | | - | user = { |
369 | | - | 'id': data['pk'], |
370 | | - | 'full_name': data['full_name'], |
371 | | - | 'biography': data['biography'], |
372 | | - | 'edge_followed_by': data['follower_count'], |
373 | | - | 'edge_follow': data['following_count'], |
374 | | - | 'is_business_account': data['is_business'], |
375 | | - | 'is_verified': data['is_verified'], |
376 | | - | 'profile_pic_url_hd': data['hd_profile_pic_url_info']['url'] |
377 | | - | } |
378 | | - | if 'public_email' in data and data['public_email']: |
379 | | - | user['email'] = data['public_email'] |
380 | | - | if 'fb_page_call_to_action_id' in data and data['fb_page_call_to_action_id']: |
381 | | - | user['connected_fb_page'] = data['fb_page_call_to_action_id'] |
382 | | - | if 'whatsapp_number' in data and data['whatsapp_number']: |
383 | | - | user['whatsapp_number'] = data['whatsapp_number'] |
384 | | - | if 'city_name' in data and data['city_name']: |
385 | | - | user['city_name'] = data['city_name'] |
386 | | - | if 'address_street' in data and data['address_street']: |
387 | | - | user['address_street'] = data['address_street'] |
388 | | - | if 'contact_phone_number' in data and data['contact_phone_number']: |
389 | | - | user['contact_phone_number'] = data['contact_phone_number'] |
390 | | - | |
391 | | - | json_file_name = self.output_dir + "/" + self.target + "_info.json" |
392 | | - | with open(json_file_name, 'w') as f: |
393 | | - | json.dump(user, f) |
394 | | - | |
395 | | - | except ClientError as e: |
396 | | - | print(e) |
397 | | - | pc.printout("Oops... " + str(self.target) + " non exist, please enter a valid username.", pc.RED) |
398 | | - | pc.printout("\n") |
399 | | - | exit(2) |
400 | | - | |
401 | | - | def get_total_likes(self): |
402 | | - | if self.check_private_profile(): |
403 | | - | return |
404 | | - | |
405 | | - | pc.printout("Searching for " + self.target + " total likes...\n") |
406 | | - | |
407 | | - | like_counter = 0 |
408 | | - | posts = 0 |
409 | | - | |
410 | | - | data = self.__get_feed__() |
411 | | - | |
412 | | - | for post in data: |
413 | | - | like_counter += post['like_count'] |
414 | | - | posts += 1 |
415 | | - | |
416 | | - | if self.writeFile: |
417 | | - | file_name = self.output_dir + "/" + self.target + "_likes.txt" |
418 | | - | file = open(file_name, "w") |
419 | | - | file.write(str(like_counter) + " likes in " + str(like_counter) + " posts\n") |
420 | | - | file.close() |
421 | | - | |
422 | | - | if self.jsonDump: |
423 | | - | json_data = { |
424 | | - | 'like_counter': like_counter, |
425 | | - | 'posts': like_counter |
426 | | - | } |
427 | | - | json_file_name = self.output_dir + "/" + self.target + "_likes.json" |
428 | | - | with open(json_file_name, 'w') as f: |
429 | | - | json.dump(json_data, f) |
430 | | - | |
431 | | - | pc.printout(str(like_counter), pc.MAGENTA) |
432 | | - | pc.printout(" likes in " + str(posts) + " posts\n") |
433 | | - | |
434 | | - | def get_media_type(self): |
435 | | - | if self.check_private_profile(): |
436 | | - | return |
437 | | - | |
438 | | - | pc.printout("Searching for " + self.target + " captions...\n") |
439 | | - | |
440 | | - | counter = 0 |
441 | | - | photo_counter = 0 |
442 | | - | video_counter = 0 |
443 | | - | |
444 | | - | data = self.__get_feed__() |
445 | | - | |
446 | | - | for post in data: |
447 | | - | if "media_type" in post: |
448 | | - | if post["media_type"] == 1: |
449 | | - | photo_counter = photo_counter + 1 |
450 | | - | elif post["media_type"] == 2: |
451 | | - | video_counter = video_counter + 1 |
452 | | - | counter = counter + 1 |
453 | | - | sys.stdout.write("\rChecked %i" % counter) |
454 | | - | sys.stdout.flush() |
455 | | - | |
456 | | - | sys.stdout.write(" posts") |
457 | | - | sys.stdout.flush() |
458 | | - | |
459 | | - | if counter > 0: |
460 | | - | |
461 | | - | if self.writeFile: |
462 | | - | file_name = self.output_dir + "/" + self.target + "_mediatype.txt" |
463 | | - | file = open(file_name, "w") |
464 | | - | file.write(str(photo_counter) + " photos and " + str(video_counter) + " video posted by target\n") |
465 | | - | file.close() |
466 | | - | |
467 | | - | pc.printout("\nWoohoo! We found " + str(photo_counter) + " photos and " + str(video_counter) + |
468 | | - | " video posted by target\n", pc.GREEN) |
469 | | - | |
470 | | - | if self.jsonDump: |
471 | | - | json_data = { |
472 | | - | "photos": photo_counter, |
473 | | - | "videos": video_counter |
474 | | - | } |
475 | | - | json_file_name = self.output_dir + "/" + self.target + "_mediatype.json" |
476 | | - | with open(json_file_name, 'w') as f: |
477 | | - | json.dump(json_data, f) |
478 | | - | |
479 | | - | else: |
480 | | - | pc.printout("Sorry! No results found :-(\n", pc.RED) |
481 | | - | |
482 | | - | def get_people_who_commented(self): |
483 | | - | if self.check_private_profile(): |
484 | | - | return |
485 | | - | |
486 | | - | pc.printout("Searching for users who commented...\n") |
487 | | - | |
488 | | - | data = self.__get_feed__() |
489 | | - | users = [] |
490 | | - | |
491 | | - | for post in data: |
492 | | - | comments = self.__get_comments__(post['id']) |
493 | | - | for comment in comments: |
494 | | - | if not any(u['id'] == comment['user']['pk'] for u in users): |
495 | | - | user = { |
496 | | - | 'id': comment['user']['pk'], |
497 | | - | 'username': comment['user']['username'], |
498 | | - | 'full_name': comment['user']['full_name'], |
499 | | - | 'counter': 1 |
500 | | - | } |
501 | | - | users.append(user) |
502 | | - | else: |
503 | | - | for user in users: |
504 | | - | if user['id'] == comment['user']['pk']: |
505 | | - | user['counter'] += 1 |
506 | | - | break |
507 | | - | |
508 | | - | if len(users) > 0: |
509 | | - | ssort = sorted(users, key=lambda value: value['counter'], reverse=True) |
510 | | - | |
511 | | - | json_data = {} |
512 | | - | |
513 | | - | t = PrettyTable() |
514 | | - | |
515 | | - | t.field_names = ['Comments', 'ID', 'Username', 'Full Name'] |
516 | | - | t.align["Comments"] = "l" |
517 | | - | t.align["ID"] = "l" |
518 | | - | t.align["Username"] = "l" |
519 | | - | t.align["Full Name"] = "l" |
520 | | - | |
521 | | - | for u in ssort: |
522 | | - | t.add_row([str(u['counter']), u['id'], u['username'], u['full_name']]) |
523 | | - | |
524 | | - | print(t) |
525 | | - | |
526 | | - | if self.writeFile: |
527 | | - | file_name = self.output_dir + "/" + self.target + "_users_who_commented.txt" |
528 | | - | file = open(file_name, "w") |
529 | | - | file.write(str(t)) |
530 | | - | file.close() |
531 | | - | |
532 | | - | if self.jsonDump: |
533 | | - | json_data['users_who_commented'] = ssort |
534 | | - | json_file_name = self.output_dir + "/" + self.target + "_users_who_commented.json" |
535 | | - | with open(json_file_name, 'w') as f: |
536 | | - | json.dump(json_data, f) |
537 | | - | else: |
538 | | - | pc.printout("Sorry! No results found :-(\n", pc.RED) |
539 | | - | |
540 | | - | def get_people_who_tagged(self): |
541 | | - | if self.check_private_profile(): |
542 | | - | return |
543 | | - | |
544 | | - | pc.printout("Searching for users who tagged target...\n") |
545 | | - | |
546 | | - | posts = [] |
547 | | - | |
548 | | - | result = self.api.usertag_feed(self.target_id) |
549 | | - | posts.extend(result.get('items', [])) |
550 | | - | |
551 | | - | next_max_id = result.get('next_max_id') |
552 | | - | while next_max_id: |
553 | | - | results = self.api.user_feed(str(self.target_id), max_id=next_max_id) |
554 | | - | posts.extend(results.get('items', [])) |
555 | | - | next_max_id = results.get('next_max_id') |
556 | | - | |
557 | | - | if len(posts) > 0: |
558 | | - | pc.printout("\nWoohoo! We found " + str(len(posts)) + " photos\n", pc.GREEN) |
559 | | - | |
560 | | - | users = [] |
561 | | - | |
562 | | - | for post in posts: |
563 | | - | if not any(u['id'] == post['user']['pk'] for u in users): |
564 | | - | user = { |
565 | | - | 'id': post['user']['pk'], |
566 | | - | 'username': post['user']['username'], |
567 | | - | 'full_name': post['user']['full_name'], |
568 | | - | 'counter': 1 |
569 | | - | } |
570 | | - | users.append(user) |
571 | | - | else: |
572 | | - | for user in users: |
573 | | - | if user['id'] == post['user']['pk']: |
574 | | - | user['counter'] += 1 |
575 | | - | break |
576 | | - | |
577 | | - | ssort = sorted(users, key=lambda value: value['counter'], reverse=True) |
578 | | - | |
579 | | - | json_data = {} |
580 | | - | |
581 | | - | t = PrettyTable() |
582 | | - | |
583 | | - | t.field_names = ['Photos', 'ID', 'Username', 'Full Name'] |
584 | | - | t.align["Photos"] = "l" |
585 | | - | t.align["ID"] = "l" |
586 | | - | t.align["Username"] = "l" |
587 | | - | t.align["Full Name"] = "l" |
588 | | - | |
589 | | - | for u in ssort: |
590 | | - | t.add_row([str(u['counter']), u['id'], u['username'], u['full_name']]) |
591 | | - | |
592 | | - | print(t) |
593 | | - | |
594 | | - | if self.writeFile: |
595 | | - | file_name = self.output_dir + "/" + self.target + "_users_who_tagged.txt" |
596 | | - | file = open(file_name, "w") |
597 | | - | file.write(str(t)) |
598 | | - | file.close() |
599 | | - | |
600 | | - | if self.jsonDump: |
601 | | - | json_data['users_who_tagged'] = ssort |
602 | | - | json_file_name = self.output_dir + "/" + self.target + "_users_who_tagged.json" |
603 | | - | with open(json_file_name, 'w') as f: |
604 | | - | json.dump(json_data, f) |
605 | | - | else: |
606 | | - | pc.printout("Sorry! No results found :-(\n", pc.RED) |
607 | | - | |
608 | | - | def get_photo_description(self): |
609 | | - | if self.check_private_profile(): |
610 | | - | return |
611 | | - | |
612 | | - | content = requests.get("https://www.instagram.com/" + str(self.target) + "/?__a=1") |
613 | | - | data = content.json() |
614 | | - | |
615 | | - | dd = data['graphql']['user']['edge_owner_to_timeline_media']['edges'] |
616 | | - | |
617 | | - | if len(dd) > 0: |
618 | | - | pc.printout("\nWoohoo! We found " + str(len(dd)) + " descriptions\n", pc.GREEN) |
619 | | - | |
620 | | - | count = 1 |
621 | | - | |
622 | | - | t = PrettyTable(['Photo', 'Description']) |
623 | | - | t.align["Photo"] = "l" |
624 | | - | t.align["Description"] = "l" |
625 | | - | |
626 | | - | json_data = {} |
627 | | - | descriptions_list = [] |
628 | | - | |
629 | | - | for i in dd: |
630 | | - | node = i.get('node') |
631 | | - | descr = node.get('accessibility_caption') |
632 | | - | t.add_row([str(count), descr]) |
633 | | - | |
634 | | - | if self.jsonDump: |
635 | | - | description = { |
636 | | - | 'description': descr |
637 | | - | } |
638 | | - | descriptions_list.append(description) |
639 | | - | |
640 | | - | count += 1 |
641 | | - | |
642 | | - | if self.writeFile: |
643 | | - | file_name = self.output_dir + "/" + self.target + "_photodes.txt" |
644 | | - | file = open(file_name, "w") |
645 | | - | file.write(str(t)) |
646 | | - | file.close() |
647 | | - | |
648 | | - | if self.jsonDump: |
649 | | - | json_data['descriptions'] = descriptions_list |
650 | | - | json_file_name = self.output_dir + "/" + self.target + "_descriptions.json" |
651 | | - | with open(json_file_name, 'w') as f: |
652 | | - | json.dump(json_data, f) |
653 | | - | |
654 | | - | print(t) |
655 | | - | else: |
656 | | - | pc.printout("Sorry! No results found :-(\n", pc.RED) |
657 | | - | |
658 | | - | def get_user_propic(self): |
659 | | - | |
660 | | - | try: |
661 | | - | endpoint = 'users/{user_id!s}/full_detail_info/'.format(**{'user_id': self.target_id}) |
662 | | - | content = self.api._call_api(endpoint) |
663 | | - | |
664 | | - | data = content['user_detail']['user'] |
665 | | - | |
666 | | - | if "hd_profile_pic_url_info" in data: |
667 | | - | URL = data["hd_profile_pic_url_info"]['url'] |
668 | | - | else: |
669 | | - | #get better quality photo |
670 | | - | items = len(data['hd_profile_pic_versions']) |
671 | | - | URL = data["hd_profile_pic_versions"][items-1]['url'] |
672 | | - | |
673 | | - | if URL != "": |
674 | | - | end = self.output_dir + "/" + self.target + "_propic.jpg" |
675 | | - | urllib.request.urlretrieve(URL, end) |
676 | | - | pc.printout("Target propic saved in output folder\n", pc.GREEN) |
677 | | - | |
678 | | - | else: |
679 | | - | pc.printout("Sorry! No results found :-(\n", pc.RED) |
680 | | - | |
681 | | - | except ClientError as e: |
682 | | - | error = json.loads(e.error_response) |
683 | | - | print(error['message']) |
684 | | - | print(error['error_title']) |
685 | | - | exit(2) |
686 | | - | |
687 | | - | def get_user_stories(self): |
688 | | - | if self.check_private_profile(): |
689 | | - | return |
690 | | - | |
691 | | - | pc.printout("Searching for " + self.target + " stories...\n") |
692 | | - | |
693 | | - | data = self.api.user_reel_media(str(self.target_id)) |
694 | | - | |
695 | | - | counter = 0 |
696 | | - | |
697 | | - | if data['items'] is not None: # no stories avaibile |
698 | | - | counter = data['media_count'] |
699 | | - | for i in data['items']: |
700 | | - | story_id = i["id"] |
701 | | - | if i["media_type"] == 1: # it's a photo |
702 | | - | url = i['image_versions2']['candidates'][0]['url'] |
703 | | - | end = self.output_dir + "/" + self.target + "_" + story_id + ".jpg" |
704 | | - | urllib.request.urlretrieve(url, end) |
705 | | - | |
706 | | - | elif i["media_type"] == 2: # it's a gif or video |
707 | | - | url = i['video_versions'][0]['url'] |
708 | | - | end = self.output_dir + "/" + self.target + "_" + story_id + ".mp4" |
709 | | - | urllib.request.urlretrieve(url, end) |
710 | | - | |
711 | | - | if counter > 0: |
712 | | - | pc.printout(str(counter) + " target stories saved in output folder\n", pc.GREEN) |
713 | | - | else: |
714 | | - | pc.printout("Sorry! No results found :-(\n", pc.RED) |
715 | | - | |
716 | | - | def get_people_tagged_by_user(self): |
717 | | - | pc.printout("Searching for users tagged by target...\n") |
718 | | - | |
719 | | - | ids = [] |
720 | | - | username = [] |
721 | | - | full_name = [] |
722 | | - | post = [] |
723 | | - | counter = 1 |
724 | | - | |
725 | | - | data = self.__get_feed__() |
726 | | - | |
727 | | - | try: |
728 | | - | for i in data: |
729 | | - | if "usertags" in i: |
730 | | - | c = i.get('usertags').get('in') |
731 | | - | for cc in c: |
732 | | - | if cc.get('user').get('pk') not in ids: |
733 | | - | ids.append(cc.get('user').get('pk')) |
734 | | - | username.append(cc.get('user').get('username')) |
735 | | - | full_name.append(cc.get('user').get('full_name')) |
736 | | - | post.append(1) |
737 | | - | else: |
738 | | - | index = ids.index(cc.get('user').get('pk')) |
739 | | - | post[index] += 1 |
740 | | - | counter = counter + 1 |
741 | | - | except AttributeError as ae: |
742 | | - | pc.printout("\nERROR: an error occurred: ", pc.RED) |
743 | | - | print(ae) |
744 | | - | print("") |
745 | | - | pass |
746 | | - | |
747 | | - | if len(ids) > 0: |
748 | | - | t = PrettyTable() |
749 | | - | |
750 | | - | t.field_names = ['Posts', 'Full Name', 'Username', 'ID'] |
751 | | - | t.align["Posts"] = "l" |
752 | | - | t.align["Full Name"] = "l" |
753 | | - | t.align["Username"] = "l" |
754 | | - | t.align["ID"] = "l" |
755 | | - | |
756 | | - | pc.printout("\nWoohoo! We found " + str(len(ids)) + " (" + str(counter) + ") users\n", pc.GREEN) |
757 | | - | |
758 | | - | json_data = {} |
759 | | - | tagged_list = [] |
760 | | - | |
761 | | - | for i in range(len(ids)): |
762 | | - | t.add_row([post[i], full_name[i], username[i], str(ids[i])]) |
763 | | - | |
764 | | - | if self.jsonDump: |
765 | | - | tag = { |
766 | | - | 'post': post[i], |
767 | | - | 'full_name': full_name[i], |
768 | | - | 'username': username[i], |
769 | | - | 'id': ids[i] |
770 | | - | } |
771 | | - | tagged_list.append(tag) |
772 | | - | |
773 | | - | if self.writeFile: |
774 | | - | file_name = self.output_dir + "/" + self.target + "_tagged.txt" |
775 | | - | file = open(file_name, "w") |
776 | | - | file.write(str(t)) |
777 | | - | file.close() |
778 | | - | |
779 | | - | if self.jsonDump: |
780 | | - | json_data['tagged'] = tagged_list |
781 | | - | json_file_name = self.output_dir + "/" + self.target + "_tagged.json" |
782 | | - | with open(json_file_name, 'w') as f: |
783 | | - | json.dump(json_data, f) |
784 | | - | |
785 | | - | print(t) |
786 | | - | else: |
787 | | - | pc.printout("Sorry! No results found :-(\n", pc.RED) |
788 | | - | |
789 | 92 | | def get_user(self, username): |
790 | 93 | | try: |
791 | 94 | | content = self.api.username_info(username) |
| skipped 9 lines |
801 | 104 | | |
802 | 105 | | return user |
803 | 106 | | except ClientError as e: |
804 | | - | pc.printout('ClientError {0!s} (Code: {1:d}, Response: {2!s})'.format(e.msg, e.code, e.error_response), pc.RED) |
| 107 | + | # pc.printout('ClientError {0!s} (Code: {1:d}, Response: {2!s})'.format(e.msg, e.code, e.error_response), pc.RED) |
805 | 108 | | error = json.loads(e.error_response) |
806 | | - | if 'message' in error: |
807 | | - | print(error['message']) |
808 | | - | if 'error_title' in error: |
809 | | - | print(error['error_title']) |
810 | 109 | | if 'challenge' in error: |
811 | 110 | | print("Please follow this link to complete the challenge: " + error['challenge']['url']) |
812 | | - | sys.exit(2) |
813 | | - | |
814 | | - | |
815 | | - | def set_write_file(self, flag): |
816 | | - | if flag: |
817 | | - | pc.printout("Write to file: ") |
818 | | - | pc.printout("enabled", pc.GREEN) |
819 | | - | pc.printout("\n") |
820 | | - | else: |
821 | | - | pc.printout("Write to file: ") |
822 | | - | pc.printout("disabled", pc.RED) |
823 | | - | pc.printout("\n") |
824 | | - | |
825 | | - | self.writeFile = flag |
826 | | - | |
827 | | - | def set_json_dump(self, flag): |
828 | | - | if flag: |
829 | | - | pc.printout("Export to JSON: ") |
830 | | - | pc.printout("enabled", pc.GREEN) |
831 | | - | pc.printout("\n") |
832 | | - | else: |
833 | | - | pc.printout("Export to JSON: ") |
834 | | - | pc.printout("disabled", pc.RED) |
835 | | - | pc.printout("\n") |
836 | | - | |
837 | | - | self.jsonDump = flag |
| 111 | + | sys.exit(2) |
| 112 | + | return None |
838 | 113 | | |
839 | 114 | | def login(self, u, p): |
840 | 115 | | try: |
| skipped 503 lines |
1344 | 619 | | print(t) |
1345 | 620 | | else: |
1346 | 621 | | pc.printout("Sorry! No results found :-(\n", pc.RED) |
1347 | | - | |
1348 | | - | def get_comments(self): |
1349 | | - | if self.check_private_profile(): |
1350 | | - | return |
1351 | | - | |
1352 | | - | pc.printout("Searching for users who commented...\n") |
1353 | | - | |
1354 | | - | data = self.__get_feed__() |
1355 | | - | users = [] |
1356 | | - | |
1357 | | - | for post in data: |
1358 | | - | comments = self.__get_comments__(post['id']) |
1359 | | - | for comment in comments: |
1360 | | - | print(comment['text']) |
1361 | | - | |
1362 | | - | # if not any(u['id'] == comment['user']['pk'] for u in users): |
1363 | | - | # user = { |
1364 | | - | # 'id': comment['user']['pk'], |
1365 | | - | # 'username': comment['user']['username'], |
1366 | | - | # 'full_name': comment['user']['full_name'], |
1367 | | - | # 'counter': 1 |
1368 | | - | # } |
1369 | | - | # users.append(user) |
1370 | | - | # else: |
1371 | | - | # for user in users: |
1372 | | - | # if user['id'] == comment['user']['pk']: |
1373 | | - | # user['counter'] += 1 |
1374 | | - | # break |
1375 | | - | |
1376 | | - | if len(users) > 0: |
1377 | | - | ssort = sorted(users, key=lambda value: value['counter'], reverse=True) |
1378 | | - | |
1379 | | - | json_data = {} |
1380 | | - | |
1381 | | - | t = PrettyTable() |
1382 | | - | |
1383 | | - | t.field_names = ['Comments', 'ID', 'Username', 'Full Name'] |
1384 | | - | t.align["Comments"] = "l" |
1385 | | - | t.align["ID"] = "l" |
1386 | | - | t.align["Username"] = "l" |
1387 | | - | t.align["Full Name"] = "l" |
1388 | | - | |
1389 | | - | for u in ssort: |
1390 | | - | t.add_row([str(u['counter']), u['id'], u['username'], u['full_name']]) |
1391 | | - | |
1392 | | - | print(t) |
1393 | | - | |
1394 | | - | if self.writeFile: |
1395 | | - | file_name = self.output_dir + "/" + self.target + "_users_who_commented.txt" |
1396 | | - | file = open(file_name, "w") |
1397 | | - | file.write(str(t)) |
1398 | | - | file.close() |
1399 | | - | |
1400 | | - | if self.jsonDump: |
1401 | | - | json_data['users_who_commented'] = ssort |
1402 | | - | json_file_name = self.output_dir + "/" + self.target + "_users_who_commented.json" |
1403 | | - | with open(json_file_name, 'w') as f: |
1404 | | - | json.dump(json_data, f) |
1405 | | - | else: |
1406 | | - | pc.printout("Sorry! No results found :-(\n", pc.RED) |
1407 | | - | |
1408 | | - | def get_followers_subset(self): |
1409 | | - | if self.check_private_profile(): |
1410 | | - | return |
1411 | | - | |
1412 | | - | pc.printout("Searching for " + self.target + " followers...\n") |
1413 | | - | |
1414 | | - | target_1 = self.target |
1415 | | - | _followers_target_1 = [] |
1416 | | - | _followers_target_2 = [] |
1417 | | - | followers_subset = [] |
1418 | | - | |
1419 | | - | |
1420 | | - | rank_token = AppClient.generate_uuid() |
1421 | | - | data = self.api.user_followers(str(self.target_id), rank_token=rank_token) |
1422 | | - | |
1423 | | - | _followers_target_1.extend(data.get('users', [])) |
1424 | | - | |
1425 | | - | next_max_id = data.get('next_max_id') |
1426 | | - | while next_max_id: |
1427 | | - | sys.stdout.write("\rCatched %i followers" % len(_followers_target_1)) |
1428 | | - | sys.stdout.flush() |
1429 | | - | results = self.api.user_followers(str(self.target_id), rank_token=rank_token, max_id=next_max_id) |
1430 | | - | _followers_target_1.extend(results.get('users', [])) |
1431 | | - | next_max_id = results.get('next_max_id') |
1432 | | - | sys.stdout.write("\rCatched %i followers" % len(_followers_target_1)) |
1433 | | - | sys.stdout.flush() |
1434 | | - | |
1435 | | - | print("\n") |
1436 | | - | |
1437 | | - | pc.printout("Insert target two username: ", pc.YELLOW) |
1438 | | - | line = input() |
1439 | | - | self.setTarget(line, False) |
1440 | | - | target_2 = self.target |
1441 | | - | if self.check_private_profile(): |
1442 | | - | return |
1443 | | - | |
1444 | | - | |
1445 | | - | pc.printout("Searching for " + self.target + " followers...\n") |
1446 | | - | |
1447 | | - | rank_token = AppClient.generate_uuid() |
1448 | | - | data = self.api.user_followers(str(self.target_id), rank_token=rank_token) |
1449 | | - | |
1450 | | - | _followers_target_2.extend(data.get('users', [])) |
1451 | | - | |
1452 | | - | next_max_id = data.get('next_max_id') |
1453 | | - | while next_max_id: |
1454 | | - | sys.stdout.write("\rCatched %i followers" % len(_followers_target_2)) |
1455 | | - | sys.stdout.flush() |
1456 | | - | results = self.api.user_followers(str(self.target_id), rank_token=rank_token, max_id=next_max_id) |
1457 | | - | _followers_target_2.extend(results.get('users', [])) |
1458 | | - | next_max_id = results.get('next_max_id') |
1459 | | - | sys.stdout.write("\rCatched %i followers" % len(_followers_target_2)) |
1460 | | - | sys.stdout.flush() |
1461 | | - | |
1462 | | - | print("\n") |
1463 | | - | |
1464 | | - | for user in _followers_target_1: |
1465 | | - | ff = list(filter(lambda x: x['pk'] == user['pk'], _followers_target_2)) |
1466 | | - | if(len(ff) > 0): |
1467 | | - | f = { |
1468 | | - | 'id': ff[0]['pk'], |
1469 | | - | 'username': ff[0]['username'], |
1470 | | - | 'full_name': ff[0]['full_name'] |
1471 | | - | } |
1472 | | - | followers_subset.append(f) |
1473 | | - | |
1474 | | - | t = PrettyTable(['ID', 'Username', 'Full Name']) |
1475 | | - | t.align["ID"] = "l" |
1476 | | - | t.align["Username"] = "l" |
1477 | | - | t.align["Full Name"] = "l" |
1478 | | - | |
1479 | | - | json_data = {} |
1480 | | - | followings_subset_list = [] |
1481 | | - | |
1482 | | - | for node in followers_subset: |
1483 | | - | t.add_row([str(node['id']), node['username'], node['full_name']]) |
1484 | | - | |
1485 | | - | if self.jsonDump: |
1486 | | - | follow = { |
1487 | | - | 'id': node['id'], |
1488 | | - | 'username': node['username'], |
1489 | | - | 'full_name': node['full_name'] |
1490 | | - | } |
1491 | | - | followings_subset_list.append(follow) |
1492 | | - | |
1493 | | - | if self.writeFile: |
1494 | | - | file_name = self.output_dir + "/" + target_1 + "-" + target_2 + "_followers.txt" |
1495 | | - | file = open(file_name, "w") |
1496 | | - | file.write(str(t)) |
1497 | | - | file.close() |
1498 | | - | |
1499 | | - | if self.jsonDump: |
1500 | | - | json_data['followers'] = followers_subset |
1501 | | - | json_file_name = self.output_dir + "/" + target_1 + "-" + target_2 + "_followers.txt" |
1502 | | - | with open(json_file_name, 'w') as f: |
1503 | | - | json.dump(json_data, f) |
1504 | | - | |
1505 | | - | print(t) |
1506 | | - | pc.printout("Founded " + str(len(followers_subset)) + " users!\n", pc.GREEN) |
1507 | | - | |
1508 | | - | def get_followings_subset(self): |
1509 | | - | if self.check_private_profile(): |
1510 | | - | return |
1511 | | - | |
1512 | | - | pc.printout("Searching for " + self.target + " followings...\n") |
1513 | | - | |
1514 | | - | target_1 = self.target |
1515 | | - | _followings_target_1 = [] |
1516 | | - | _followings_target_2 = [] |
1517 | | - | followers_subset = [] |
1518 | | - | |
1519 | | - | |
1520 | | - | rank_token = AppClient.generate_uuid() |
1521 | | - | data = self.api.user_followers(str(self.target_id), rank_token=rank_token) |
1522 | | - | |
1523 | | - | _followings_target_1.extend(data.get('users', [])) |
1524 | | - | |
1525 | | - | next_max_id = data.get('next_max_id') |
1526 | | - | while next_max_id: |
1527 | | - | sys.stdout.write("\rCatched %i followings" % len(_followings_target_1)) |
1528 | | - | sys.stdout.flush() |
1529 | | - | results = self.api.user_followers(str(self.target_id), rank_token=rank_token, max_id=next_max_id) |
1530 | | - | _followings_target_1.extend(results.get('users', [])) |
1531 | | - | next_max_id = results.get('next_max_id') |
1532 | | - | sys.stdout.write("\rCatched %i followings" % len(_followings_target_2)) |
1533 | | - | sys.stdout.flush() |
1534 | | - | |
1535 | | - | print("\n") |
1536 | | - | |
1537 | | - | pc.printout("Insert target two username: ", pc.YELLOW) |
1538 | | - | line = input() |
1539 | | - | self.setTarget(line, False) |
1540 | | - | target_2 = self.target |
1541 | | - | if self.check_private_profile(): |
1542 | | - | return |
1543 | | - | |
1544 | | - | |
1545 | | - | pc.printout("Searching for " + self.target + " followings...\n") |
1546 | | - | |
1547 | | - | rank_token = AppClient.generate_uuid() |
1548 | | - | data = self.api.user_followers(str(self.target_id), rank_token=rank_token) |
1549 | | - | |
1550 | | - | _followings_target_2.extend(data.get('users', [])) |
1551 | | - | |
1552 | | - | next_max_id = data.get('next_max_id') |
1553 | | - | while next_max_id: |
1554 | | - | sys.stdout.write("\rCatched %i followings" % len(_followings_target_2)) |
1555 | | - | sys.stdout.flush() |
1556 | | - | results = self.api.user_followers(str(self.target_id), rank_token=rank_token, max_id=next_max_id) |
1557 | | - | _followings_target_2.extend(results.get('users', [])) |
1558 | | - | next_max_id = results.get('next_max_id') |
1559 | | - | sys.stdout.write("\rCatched %i followings" % len(_followings_target_2)) |
1560 | | - | sys.stdout.flush() |
1561 | | - | |
1562 | | - | print("\n") |
1563 | | - | |
1564 | | - | for user in _followings_target_1: |
1565 | | - | ff = list(filter(lambda x: x['pk'] == user['pk'], _followings_target_2)) |
1566 | | - | if(len(ff) > 0): |
1567 | | - | f = { |
1568 | | - | 'id': ff[0]['pk'], |
1569 | | - | 'username': ff[0]['username'], |
1570 | | - | 'full_name': ff[0]['full_name'] |
1571 | | - | } |
1572 | | - | followers_subset.append(f) |
1573 | | - | |
1574 | | - | t = PrettyTable(['ID', 'Username', 'Full Name']) |
1575 | | - | t.align["ID"] = "l" |
1576 | | - | t.align["Username"] = "l" |
1577 | | - | t.align["Full Name"] = "l" |
1578 | | - | |
1579 | | - | json_data = {} |
1580 | | - | followings_subset_list = [] |
1581 | | - | |
1582 | | - | for node in followers_subset: |
1583 | | - | t.add_row([str(node['id']), node['username'], node['full_name']]) |
1584 | | - | |
1585 | | - | if self.jsonDump: |
1586 | | - | follow = { |
1587 | | - | 'id': node['id'], |
1588 | | - | 'username': node['username'], |
1589 | | - | 'full_name': node['full_name'] |
1590 | | - | } |
1591 | | - | followings_subset_list.append(follow) |
1592 | | - | |
1593 | | - | if self.writeFile: |
1594 | | - | file_name = self.output_dir + "/" + target_1 + "-" + target_2 + "_followings.txt" |
1595 | | - | file = open(file_name, "w") |
1596 | | - | file.write(str(t)) |
1597 | | - | file.close() |
1598 | | - | |
1599 | | - | if self.jsonDump: |
1600 | | - | json_data['followings'] = followers_subset |
1601 | | - | json_file_name = self.output_dir + "/" + target_1 + "-" + target_2 + "_followings.txt" |
1602 | | - | with open(json_file_name, 'w') as f: |
1603 | | - | json.dump(json_data, f) |
1604 | | - | |
1605 | | - | print(t) |
1606 | | - | pc.printout("Founded " + str(len(followers_subset)) + " users!\n", pc.GREEN) |
1607 | | - | |
1608 | 622 | | |
1609 | 623 | | def clear_cache(self): |
1610 | 624 | | try: |
| skipped 8 lines |