-
Notifications
You must be signed in to change notification settings - Fork 76
/
Copy pathstart.py
122 lines (110 loc) · 4.66 KB
/
start.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import argparse
import getpass
import json
import os
import requests
from display import display_to_terminal
def get_credential():
if not os.path.exists('credential.json'):
return
try:
with open('credential.json') as json_data:
credential = json.load(json_data)
return credential
except FileNotFoundError:
print('credential.json file not found in current directory. Exiting.')
exit()
def fetch_news_feed(session):
res = session.get('https://i.instagram.com/api/v1/feed/timeline/', headers={
'user-agent': 'Mozilla/5.0 (Linux; Android 6.0.1; SM-G935T Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36 Instagram 8.4.0 Android (23/6.0.1; 560dpi; 1440x2560; samsung; SM-G935T; hero2qltetmo; qcom; en_US)',
'cookie':'sessionid={0};'.format(session.cookies['sessionid'])
})
if res.status_code != 200:
print('ERROR: got '+str(res.status_code)+' when fetching!')
exit()
res = json.loads(res.text)
posts_info = {}
for item in res['items']:
if 'user' not in item: continue
username = item['user']['username']
key = username + '_' + str(item['taken_at']) + '.jpg'
try:
posts_info[key] = {
'username': username,
'caption': item['caption']['text'] if item['caption'] else '',
'image_url': item['image_versions2']['candidates'][0]['url'],
'likes': str(item['like_count']) if item['like_count'] else '0',
'site_url': 'https://www.instagram.com/p/' + item['code'] + '/?taken-by=' + username
}
except KeyError:
pass
return posts_info
def save_image(posts_info, session):
if not os.path.exists('images'):
os.makedirs('images')
for key in posts_info:
res = session.get(posts_info[key]['image_url'])
with open('images/' + key, 'wb') as f:
for chunk in res.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
def remove_images():
if not os.path.isdir('./images'):
return
file_list = os.listdir('./images/')
for filename in file_list:
os.remove('./images/' + filename)
def save_credentials(credential, permission):
if not permission:
return
with open('credential.json', 'w') as _file:
json.dump(credential, _file)
def get_login_session(credential):
session = requests.Session()
session.headers.update({'Referer': 'https://www.instagram.com/'})
req = session.get('https://www.instagram.com/')
session.headers.update({'X-CSRFToken': req.cookies['csrftoken']})
login_response = session.post('https://www.instagram.com/accounts/login/ajax/', data=credential, allow_redirects=True).json()
if 'two_factor_required' in login_response and login_response['two_factor_required']:
identifier = login_response['two_factor_info']['two_factor_identifier']
username = credential['username']
verification_code = input('2FA Verification Code: ')
verification_data = {'username': username, 'verificationCode': verification_code, 'identifier': identifier}
two_factor_response = session.post('https://www.instagram.com/accounts/login/ajax/two_factor/', data=verification_data, allow_redirects=True).json()
if two_factor_response['authenticated']:
return session, two_factor_response
else:
return None, two_factor_response
return session, login_response
def login(credential):
if credential:
session, _ = get_login_session(credential)
return session
user, pwd = '', ''
while True:
user = input('Username: ')
pwd = getpass.getpass(prompt='Password: ')
session, res = get_login_session({'username': user, 'password': pwd})
if res['authenticated']:
break
if not res['authenticated']:
print('Bad username or password')
if res['status'] == 'fail':
print(res['message'])
exit()
permission = input('save credentials(y/N)?: ')
credential = {'username': user, 'password': pwd}
save_credentials(credential, permission == 'y')
return session
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--color', action='store_true', help='Display image with color')
display_color = parser.parse_args().color
credential = get_credential()
session = login(credential)
remove_images()
posts_info = fetch_news_feed(session)
save_image(posts_info, session)
display_to_terminal(posts_info, display_color)
if __name__ == '__main__':
main()