Advertisement
Guest User

Untitled

a guest
Aug 26th, 2016
1,878
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.76 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import requests
  4. import random
  5. import json
  6. import hashlib
  7. import hmac
  8. import urllib
  9.  
  10. class InstagramAPI:
  11. API_URL = 'https://i.instagram.com/api/v1/'
  12. USER_AGENT = 'Instagram 8.2.0 Android (18/4.3; 320dpi; 720x1280; Xiaomi; HM 1SW; armani; qcom; en_US)'
  13. IG_SIG_KEY = '55e91155636eaa89ba5ed619eb4645a4daf1103f2161dbfe6fd94d5ea7716095'
  14. EXPERIMENTS = 'ig_android_progressive_jpeg,ig_creation_growth_holdout,ig_android_report_and_hide,ig_android_new_browser,ig_android_enable_share_to_whatsapp,ig_android_direct_drawing_in_quick_cam_universe,ig_android_huawei_app_badging,ig_android_universe_video_production,ig_android_asus_app_badging,ig_android_direct_plus_button,ig_android_ads_heatmap_overlay_universe,ig_android_http_stack_experiment_2016,ig_android_infinite_scrolling,ig_fbns_blocked,ig_android_white_out_universe,ig_android_full_people_card_in_user_list,ig_android_post_auto_retry_v7_21,ig_fbns_push,ig_android_feed_pill,ig_android_profile_link_iab,ig_explore_v3_us_holdout,ig_android_histogram_reporter,ig_android_anrwatchdog,ig_android_search_client_matching,ig_android_high_res_upload_2,ig_android_new_browser_pre_kitkat,ig_android_2fac,ig_android_grid_video_icon,ig_android_white_camera_universe,ig_android_disable_chroma_subsampling,ig_android_share_spinner,ig_android_explore_people_feed_icon,ig_explore_v3_android_universe,ig_android_media_favorites,ig_android_nux_holdout,ig_android_search_null_state,ig_android_react_native_notification_setting,ig_android_ads_indicator_change_universe,ig_android_video_loading_behavior,ig_android_black_camera_tab,liger_instagram_android_univ,ig_explore_v3_internal,ig_android_direct_emoji_picker,ig_android_prefetch_explore_delay_time,ig_android_business_insights_qe,ig_android_direct_media_size,ig_android_enable_client_share,ig_android_promoted_posts,ig_android_app_badging_holdout,ig_android_ads_cta_universe,ig_android_mini_inbox_2,ig_android_feed_reshare_button_nux,ig_android_boomerang_feed_attribution,ig_android_fbinvite_qe,ig_fbns_shared,ig_android_direct_full_width_media,ig_android_hscroll_profile_chaining,ig_android_feed_unit_footer,ig_android_media_tighten_space,ig_android_private_follow_request,ig_android_inline_gallery_backoff_hours_universe,ig_android_direct_thread_ui_rewrite,ig_android_rendering_controls,ig_android_ads_full_width_cta_universe,ig_video_max_duration_qe_preuniverse,ig_android_prefetch_explore_expire_time,ig_timestamp_public_test,ig_android_profile,ig_android_dv2_consistent_http_realtime_response,ig_android_enable_share_to_messenger,ig_explore_v3,ig_ranking_following,ig_android_pending_request_search_bar,ig_android_feed_ufi_redesign,ig_android_video_pause_logging_fix,ig_android_default_folder_to_camera,ig_android_video_stitching_7_23,ig_android_profanity_filter,ig_android_business_profile_qe,ig_android_search,ig_android_boomerang_entry,ig_android_inline_gallery_universe,ig_android_ads_overlay_design_universe,ig_android_options_app_invite,ig_android_view_count_decouple_likes_universe,ig_android_periodic_analytics_upload_v2,ig_android_feed_unit_hscroll_auto_advance,ig_peek_profile_photo_universe,ig_android_ads_holdout_universe,ig_android_prefetch_explore,ig_android_direct_bubble_icon,ig_video_use_sve_universe,ig_android_inline_gallery_no_backoff_on_launch_universe,ig_android_image_cache_multi_queue,ig_android_camera_nux,ig_android_immersive_viewer,ig_android_dense_feed_unit_cards,ig_android_sqlite_dev,ig_android_exoplayer,ig_android_add_to_last_post,ig_android_direct_public_threads,ig_android_prefetch_venue_in_composer,ig_android_bigger_share_button,ig_android_dv2_realtime_private_share,ig_android_non_square_first,ig_android_video_interleaved_v2,ig_android_follow_search_bar,ig_android_last_edits,ig_android_video_download_logging,ig_android_ads_loop_count_universe,ig_android_swipeable_filters_blacklist,ig_android_boomerang_layout_white_out_universe,ig_android_ads_carousel_multi_row_universe,ig_android_mentions_invite_v2,ig_android_direct_mention_qe,ig_android_following_follower_social_context'
  15. SIG_KEY_VERSION = '4'
  16.  
  17. #username # Instagram username
  18. #password # Instagram password
  19. #debug # Debug
  20. #uuid # UUID
  21. #device_id # Device ID
  22. #username_id # Username ID
  23. #token # _csrftoken
  24. #isLoggedIn # Session status
  25. #rank_token # Rank token
  26. #IGDataPath # Data storage path
  27.  
  28. def __init__(self, username, password, debug = False, IGDataPath = None):
  29. m = hashlib.md5()
  30. m.update(username.encode('utf-8') + password.encode('utf-8'))
  31. self.device_id = self.generateDeviceId(m.hexdigest())
  32. self.setUser(username, password)
  33. self.isLoggedIn = False
  34. self.LastResponse = None
  35.  
  36. def setUser(self, username, password):
  37. self.username = username
  38. self.password = password
  39.  
  40. self.uuid = self.generateUUID(True)
  41.  
  42. # TODO save data to file...
  43.  
  44. def login(self, force = False):
  45. if (not self.isLoggedIn or force):
  46. self.s = requests.Session()
  47. # if you need proxy make something like this:
  48. # self.s.proxies = {"https" : "http://proxyip:proxyport"}
  49. if (self.SendRequest('si/fetch_headers/?challenge_type=signup&guid=' + self.generateUUID(False), None, True)):
  50.  
  51. data = {'phone_id' : self.generateUUID(True),
  52. '_csrftoken' : self.LastResponse.cookies['csrftoken'],
  53. 'username' : self.username,
  54. 'guid' : self.uuid,
  55. 'device_id' : self.device_id,
  56. 'password' : self.password,
  57. 'login_attempt_count' : '0'}
  58.  
  59. if (self.SendRequest('accounts/login/', self.generateSignature(json.dumps(data)), True)):
  60. self.isLoggedIn = True
  61. self.username_id = self.LastJson["logged_in_user"]["pk"]
  62. self.rank_token = "%s_%s" % (self.username_id, self.uuid)
  63. self.token = self.LastResponse.cookies["csrftoken"]
  64.  
  65. self.syncFeatures()
  66. self.autoCompleteUserList()
  67. self.timelineFeed()
  68. self.getv2Inbox()
  69. self.getRecentActivity()
  70. print ("Login success!\n")
  71. return True;
  72.  
  73. def syncFeatures(self):
  74. data = json.dumps({
  75. '_uuid' : self.uuid,
  76. '_uid' : self.username_id,
  77. 'id' : self.username_id,
  78. '_csrftoken' : self.token,
  79. 'experiments' : self.EXPERIMENTS
  80. })
  81. return self.SendRequest('qe/sync/', self.generateSignature(data))
  82.  
  83. def autoCompleteUserList(self):
  84. return self.SendRequest('friendships/autocomplete_user_list/')
  85.  
  86. def timelineFeed(self):
  87. return self.SendRequest('feed/timeline/')
  88.  
  89. def megaphoneLog(self):
  90. return self.SendRequest('megaphone/log/')
  91.  
  92. def expose(self):
  93. data = json.dumps({
  94. '_uuid' : self.uuid,
  95. '_uid' : self.username_id,
  96. 'id' : self.username_id,
  97. '_csrftoken' : self.token,
  98. 'experiment' : 'ig_android_profile_contextual_feed'
  99. })
  100. return self.SendRequest('qe/expose/', self.generateSignature(data))
  101.  
  102. def logout(self):
  103. logout = self.SendRequest('accounts/logout/')
  104. # TODO Instagram.php 180-185
  105.  
  106. def uploadPhoto(self, photo, caption = None, upload_id = None):
  107. # TODO Instagram.php 200-290
  108. return False
  109.  
  110. def uploadVideo(self, video, caption = None):
  111. # TODO Instagram.php 290-415
  112. return False
  113.  
  114. def direct_share(self, media_id, recipients, text = None):
  115. # TODO Instagram.php 420-490
  116. return False
  117.  
  118. def configureVideo(upload_id, video, caption = ''):
  119. # TODO Instagram.php 490-530
  120. return False
  121.  
  122. def configure(upload_id, photo, caption = ''):
  123. # TODO Instagram.php 530-570
  124. return False
  125.  
  126. def editMedia(self, mediaId, captionText = ''):
  127. data = json.dumps({
  128. '_uuid' : self.uuid,
  129. '_uid' : self.username_id,
  130. '_csrftoken' : self.token,
  131. 'caption_text' : captionText
  132. })
  133. return self.SendRequest('media/'+ str(mediaId) +'/edit_media/', self.generateSignature(data))
  134.  
  135. def removeSelftag(self, mediaId):
  136. data = json.dumps({
  137. '_uuid' : self.uuid,
  138. '_uid' : self.username_id,
  139. '_csrftoken' : self.token
  140. })
  141. return self.SendRequest('media/'+ str(mediaId) +'/remove/', self.generateSignature(data))
  142.  
  143. def mediaInfo(self, mediaId):
  144. data = json.dumps({
  145. '_uuid' : self.uuid,
  146. '_uid' : self.username_id,
  147. '_csrftoken' : self.token,
  148. 'media_id' : mediaId
  149. })
  150. return self.SendRequest('media/'+ str(mediaId) +'/info/', self.generateSignature(data))
  151.  
  152. def deleteMedia(self, mediaId):
  153. data = json.dumps({
  154. '_uuid' : self.uuid,
  155. '_uid' : self.username_id,
  156. '_csrftoken' : self.token,
  157. 'media_id' : mediaId
  158. })
  159. return self.SendRequest('media/'+ str(mediaId) +'/delete/', self.generateSignature(data))
  160.  
  161. def comment(self, mediaId, commentText):
  162. data = json.dumps({
  163. '_uuid' : self.uuid,
  164. '_uid' : self.username_id,
  165. '_csrftoken' : self.token,
  166. 'comment_text' : commentText
  167. })
  168. return self.SendRequest('media/'+ str(mediaId) +'/comment/', self.generateSignature(data))
  169.  
  170. def deleteComment(self, mediaId, captionText, commentId):
  171. data = json.dumps({
  172. '_uuid' : self.uuid,
  173. '_uid' : self.username_id,
  174. '_csrftoken' : self.token,
  175. 'caption_text' : captionText
  176. })
  177. return self.SendRequest('media/'+ str(mediaId) +'/comment/'+ str(commentId) +'/delete/', self.generateSignature(data))
  178.  
  179. def changeProfilePicture(self, photo):
  180. # TODO Instagram.php 705-775
  181. return False
  182.  
  183. def removeProfilePicture(self):
  184. data = json.dumps({
  185. '_uuid' : self.uuid,
  186. '_uid' : self.username_id,
  187. '_csrftoken' : self.token
  188. })
  189. return self.SendRequest('accounts/remove_profile_picture/', self.generateSignature(data))
  190.  
  191. def setPrivateAccount(self):
  192. data = json.dumps({
  193. '_uuid' : self.uuid,
  194. '_uid' : self.username_id,
  195. '_csrftoken' : self.token
  196. })
  197. return self.SendRequest('accounts/set_private/', self.generateSignature(data))
  198.  
  199. def setPublicAccount(self):
  200. data = json.dumps({
  201. '_uuid' : self.uuid,
  202. '_uid' : self.username_id,
  203. '_csrftoken' : self.token
  204. })
  205. return self.SendRequest('accounts/set_public/', self.generateSignature(data))
  206.  
  207. def getProfileData(self):
  208. data = json.dumps({
  209. '_uuid' : self.uuid,
  210. '_uid' : self.username_id,
  211. '_csrftoken' : self.token
  212. })
  213. return self.SendRequest('accounts/current_user/?edit=true', self.generateSignature(data))
  214.  
  215. def editProfile(self, url, phone, first_name, biography, email, gender):
  216. data = json.dumps({
  217. '_uuid' : self.uuid,
  218. '_uid' : self.username_id,
  219. '_csrftoken' : self.token,
  220. 'external_url' : url,
  221. 'phone_number' : phone,
  222. 'username' : self.username,
  223. 'full_name' : first_name,
  224. 'biography' : biography,
  225. 'email' : email,
  226. 'gender' : gender,
  227. })
  228. return self.SendRequest('accounts/edit_profile/', self.generateSignature(data))
  229.  
  230. def getUsernameInfo(self, usernameId):
  231. return self.SendRequest('users/'+ str(usernameId) +'/info/')
  232.  
  233. def getSelfUsernameInfo(self):
  234. return self.getUsernameInfo(self.username_id)
  235.  
  236. def getRecentActivity(self):
  237. activity = self.SendRequest('news/inbox/?')
  238. # TODO Instagram.php 911-925
  239. return activity
  240.  
  241. def getFollowingRecentActivity(self):
  242. activity = self.SendRequest('news/?')
  243. # TODO Instagram.php 935-945
  244. return activity
  245.  
  246. def getv2Inbox(self):
  247. inbox = self.SendRequest('direct_v2/inbox/?')
  248. # TODO Instagram.php 950-960
  249. return inbox
  250.  
  251. def getUserTags(self, usernameId):
  252. tags = self.SendRequest('usertags/'+ str(usernameId) +'/feed/?rank_token='+ str(self.rank_token) +'&ranked_content=true&')
  253. # TODO Instagram.php 975-985
  254. return tags
  255.  
  256. def getSelfUserTags(self):
  257. return self.getUserTags(self.username_id)
  258.  
  259. def tagFeed(self, tag):
  260. userFeed = self.SendRequest('feed/tag/'+ str(tag) +'/?rank_token=' + str(self.rank_token) + '&ranked_content=true&')
  261. # TODO Instagram.php 1000-1015
  262. return userFeed
  263.  
  264. def getMediaLikers(self, mediaId):
  265. likers = self.SendRequest('media/'+ str(mediaId) +'/likers/?')
  266. # TODO Instagram.php 1025-1035
  267. return likers
  268.  
  269. def getGeoMedia(self, usernameId):
  270. locations = self.SendRequest('maps/user/'+ str(usernameId) +'/')
  271. # TODO Instagram.php 1050-1060
  272. return locations
  273.  
  274. def getSelfGeoMedia(self):
  275. return self.getGeoMedia(self.username_id)
  276.  
  277. def fbUserSearch(self, query):
  278. query = self.SendRequest('fbsearch/topsearch/?context=blended&query='+ str(query) +'&rank_token='+ str(self.rank_token))
  279. # TODO Instagram.php 1080-1090
  280. return query
  281.  
  282. def searchUsers(self, query):
  283. query = self.SendRequest('users/search/?ig_sig_key_version='+ str(self.SIG_KEY_VERSION)
  284. +'&is_typeahead=true&query='+ str(query) +'&rank_token='+ str(self.rank_token))
  285. # TODO Instagram.php 1100-1110
  286. return query
  287.  
  288. def searchUsername(self, usernameName):
  289. query = self.SendRequest('users/'+ str(usernameName) +'/usernameinfo/')
  290. # TODO Instagram.php 1080-1090
  291. return query
  292.  
  293. def syncFromAdressBook(self, contacts):
  294. return self.SendRequest('address_book/link/?include=extra_display_name,thumbnails', json.dumps(contacts))
  295.  
  296. def searchTags(self, query):
  297. query = self.SendRequest('tags/search/?is_typeahead=true&q='+ str(query) +'&rank_token='+ str(self.rank_token))
  298. # TODO Instagram.php 1160-1170
  299. return query
  300.  
  301. def getTimeline(self):
  302. query = self.SendRequest('feed/timeline/?rank_token='+ str(self.rank_token) +'&ranked_content=true&')
  303. # TODO Instagram.php 1180-1190
  304. return query
  305.  
  306. def getUserFeed(self, usernameId, maxid = '', minTimestamp = None):
  307. # TODO Instagram.php 1200-1220
  308. return False
  309.  
  310. def getSelfUserFeed(self):
  311. return self.getUserFeed(self.username_id)
  312.  
  313. def getHashtagFeed(self, hashtagString, maxid = ''):
  314. # TODO Instagram.php 1230-1250
  315. return False
  316.  
  317. def searchLocation(self, query):
  318. locationFeed = self.SendRequest('fbsearch/places/?rank_token='+ str(self.rank_token) +'&query=' + str(query))
  319. # TODO Instagram.php 1250-1270
  320. return locationFeed
  321.  
  322. def getLocationFeed(self, locationId, maxid = ''):
  323. # TODO Instagram.php 1280-1300
  324. return False
  325.  
  326. def getPopularFeed(self):
  327. popularFeed = self.SendRequest('feed/popular/?people_teaser_supported=1&rank_token='+ str(self.rank_token) +'&ranked_content=true&')
  328. # TODO Instagram.php 1315-1325
  329. return popularFeed
  330.  
  331. def getUserFollowings(self, usernameId, maxid = ''):
  332. return self.SendRequest('friendships/'+ str(usernameId) +'/following/?max_id='+ str(maxid)
  333. +'&ig_sig_key_version='+ self.SIG_KEY_VERSION +'&rank_token='+ self.rank_token)
  334.  
  335. def getSelfUsersFollowing(self):
  336. return self.getUserFollowings(self.username_id)
  337.  
  338. def getUserFollowers(self, usernameId, maxid = ''):
  339. return self.SendRequest('friendships/'+ str(usernameId) +'/followers/?max_id='+ str(maxid)
  340. +'&ig_sig_key_version='+ self.SIG_KEY_VERSION +'&rank_token='+ self.rank_token)
  341.  
  342. def getSelfUserFollowers(self):
  343. return self.getUserFollowers(self.username_id)
  344.  
  345. def like(self, mediaId):
  346. data = json.dumps({
  347. '_uuid' : self.uuid,
  348. '_uid' : self.username_id,
  349. '_csrftoken' : self.token,
  350. 'media_id' : mediaId
  351. })
  352. return self.SendRequest('media/'+ str(mediaId) +'/like/', self.generateSignature(data))
  353.  
  354. def unlike(self, mediaId):
  355. data = json.dumps({
  356. '_uuid' : self.uuid,
  357. '_uid' : self.username_id,
  358. '_csrftoken' : self.token,
  359. 'media_id' : mediaId
  360. })
  361. return self.SendRequest('media/'+ str(mediaId) +'/unlike/', self.generateSignature(data))
  362.  
  363. def getMediaComments(self, mediaId):
  364. return self.SendRequest('media/'+ mediaId +'/comments/?')
  365.  
  366. def setNameAndPhone(self, name = '', phone = ''):
  367. data = json.dumps({
  368. '_uuid' : self.uuid,
  369. '_uid' : self.username_id,
  370. 'first_name' : name,
  371. 'phone_number' : phone,
  372. '_csrftoken' : self.token
  373. })
  374. return self.SendRequest('accounts/set_phone_and_name/', self.generateSignature(data))
  375.  
  376. def getDirectShare(self):
  377. return self.SendRequest('direct_share/inbox/?')
  378.  
  379. def backup(self):
  380. # TODO Instagram.php 1470-1485
  381. return False
  382.  
  383. def follow(self, userId):
  384. data = json.dumps({
  385. '_uuid' : self.uuid,
  386. '_uid' : self.username_id,
  387. 'user_id' : userId,
  388. '_csrftoken' : self.token
  389. })
  390. return self.SendRequest('friendships/create/'+ str(userId) +'/', self.generateSignature(data))
  391.  
  392. def unfollow(self, userId):
  393. data = json.dumps({
  394. '_uuid' : self.uuid,
  395. '_uid' : self.username_id,
  396. 'user_id' : userId,
  397. '_csrftoken' : self.token
  398. })
  399. return self.SendRequest('friendships/destroy/'+ str(userId) +'/', self.generateSignature(data))
  400.  
  401. def block(self, userId):
  402. data = json.dumps({
  403. '_uuid' : self.uuid,
  404. '_uid' : self.username_id,
  405. 'user_id' : userId,
  406. '_csrftoken' : self.token
  407. })
  408. return self.SendRequest('friendships/block/'+ str(userId) +'/', self.generateSignature(data))
  409.  
  410. def unblock(self, userId):
  411. data = json.dumps({
  412. '_uuid' : self.uuid,
  413. '_uid' : self.username_id,
  414. 'user_id' : userId,
  415. '_csrftoken' : self.token
  416. })
  417. return self.SendRequest('friendships/unblock/'+ str(userId) +'/', self.generateSignature(data))
  418.  
  419. def userFriendship(self, userId):
  420. data = json.dumps({
  421. '_uuid' : self.uuid,
  422. '_uid' : self.username_id,
  423. 'user_id' : userId,
  424. '_csrftoken' : self.token
  425. })
  426. return self.SendRequest('friendships/show/'+ str(userId) +'/', self.generateSignature(data))
  427.  
  428. def getLikedMedia(self):
  429. return self.SendRequest('feed/liked/?')
  430.  
  431. def generateSignature(self, data):
  432. return 'ig_sig_key_version=' + self.SIG_KEY_VERSION + '&signed_body=' + hmac.new(self.IG_SIG_KEY.encode('utf-8'), data.encode('utf-8'), hashlib.sha256).hexdigest() + '.' + urllib.parse.quote(data)
  433.  
  434. def generateDeviceId(self, seed):
  435. volatile_seed = "12345"
  436. m = hashlib.md5()
  437. m.update(seed.encode('utf-8') + volatile_seed.encode('utf-8'))
  438. return 'android-' + m.hexdigest()[:16]
  439.  
  440. def generateUUID(self, type):
  441. uuid = '%04x%04x-%04x-%04x-%04x-%04x%04x%04x' % (random.randint(0, 0xffff),
  442. random.randint(0, 0xffff), random.randint(0, 0xffff),
  443. random.randint(0, 0x0fff) | 0x4000,
  444. random.randint(0, 0x3fff) | 0x8000,
  445. random.randint(0, 0xffff), random.randint(0, 0xffff),
  446. random.randint(0, 0xffff))
  447. if (type):
  448. return uuid
  449. else:
  450. return uuid.replace('-', '')
  451.  
  452. def buildBody(bodies, boundary):
  453. # TODO Instagram.php 1620-1645
  454. return False
  455.  
  456. def SendRequest(self, endpoint, post = None, login = False):
  457. if (not self.isLoggedIn and not login):
  458. raise Exception("Not logged in!\n")
  459. return;
  460.  
  461. self.s.headers.update ({'Connection' : 'close',
  462. 'Accept' : '*/*',
  463. 'Content-type' : 'application/x-www-form-urlencoded; charset=UTF-8',
  464. 'Cookie2' : '$Version=1',
  465. 'Accept-Language' : 'en-US',
  466. 'User-Agent' : self.USER_AGENT})
  467.  
  468. if (post != None): # POST
  469. response = self.s.post(self.API_URL + endpoint, data=post) # , verify=False
  470. else: # GET
  471. response = self.s.get(self.API_URL + endpoint) # , verify=False
  472.  
  473. if response.status_code == 200:
  474. self.LastResponse = response
  475. self.LastJson = json.loads(response.text)
  476. return True
  477. else:
  478. print ("Request return " + str(response.status_code) + " error!")
  479. return False
  480.  
  481.  
  482. InstagramAPI = InstagramAPI("login","pass")
  483. InstagramAPI.login() # login
  484. InstagramAPI.tagFeed("Minsk") # get media list by tag #Minsk
  485. media_id = InstagramAPI.LastJson # last response JSON
  486. for media in media_id['items']:
  487. print(media['image_versions2']['candidates'][00]['url'])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement