Fix get_followees() and implement get_followers()
This commit is contained in:
parent
dd513f7190
commit
1fdce16f46
12
README.rst
12
README.rst
@ -182,8 +182,7 @@ Usage as Python module
|
|||||||
You may also use parts of Instaloader as library to do other interesting
|
You may also use parts of Instaloader as library to do other interesting
|
||||||
things.
|
things.
|
||||||
|
|
||||||
For example, to get a list of all followees of a profile as well as
|
For example, to get a list of all followees and a list of all followers of a profile, do
|
||||||
their follower count, do
|
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
@ -197,8 +196,15 @@ their follower count, do
|
|||||||
|
|
||||||
# Retrieve followees
|
# Retrieve followees
|
||||||
followees = loader.get_followees(PROFILE)
|
followees = loader.get_followees(PROFILE)
|
||||||
|
print(PROFILE + " follows these profiles:")
|
||||||
for f in followees:
|
for f in followees:
|
||||||
print("%i\t%s\t%s" % (f['follower_count'], f['username'], f['full_name']))
|
print("\t%s\t%s" % (f['username'], f['full_name']))
|
||||||
|
|
||||||
|
# Retrieve followers
|
||||||
|
followers = loader.get_followers(PROFILE)
|
||||||
|
print("Followers of " + PROFILE + ":")
|
||||||
|
for f in followers:
|
||||||
|
print("\t%s\t%s" % (f['username'], f['full_name']))
|
||||||
|
|
||||||
Then, you may download all pictures of all followees with
|
Then, you may download all pictures of all followees with
|
||||||
|
|
||||||
|
119
instaloader.py
119
instaloader.py
@ -217,60 +217,87 @@ class Instaloader:
|
|||||||
raise ProfileNotExistsException("Profile {0} does not exist.".format(profile))
|
raise ProfileNotExistsException("Profile {0} does not exist.".format(profile))
|
||||||
return int(data['entry_data']['ProfilePage'][0]['user']['id'])
|
return int(data['entry_data']['ProfilePage'][0]['user']['id'])
|
||||||
|
|
||||||
def get_followees(self, profile: str) -> List[Dict[str, Any]]:
|
def get_followers(self, profile: str) -> List[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Retrieve list of followees of given profile
|
Retrieve list of followers of given profile.
|
||||||
|
To use this, one needs to be logged in and private profiles has to be followed,
|
||||||
|
otherwise this returns an empty list.
|
||||||
|
|
||||||
:param profile: Name of profile to lookup followees
|
:param profile: Name of profile to lookup followers.
|
||||||
:return: List of followees (list of dictionaries), as returned by instagram server
|
:return: List of followers (list of dictionaries).
|
||||||
"""
|
"""
|
||||||
tmpsession = copy_session(self.session)
|
tmpsession = copy_session(self.session)
|
||||||
data = self.get_json(profile, session=tmpsession)
|
header = self.default_http_header(empty_session_only=True)
|
||||||
profile_id = data['entry_data']['ProfilePage'][0]['user']['id']
|
del header['Connection']
|
||||||
query = ["q=ig_user(" + profile_id + ")+%7B%0A"
|
del header['Content-Length']
|
||||||
"++follows.",
|
header['authority'] = 'www.instagram.com'
|
||||||
str(data['entry_data']['ProfilePage'][0]['user']['follows']['count']) +
|
header['scheme'] = 'https'
|
||||||
")+%7B%0A"
|
header['accept'] = '*/*'
|
||||||
"++++count%2C%0A"
|
header['referer'] = 'https://www.instagram.com/' + profile + '/'
|
||||||
"++++page_info+%7B%0A"
|
tmpsession.headers = header
|
||||||
"++++++end_cursor%2C%0A"
|
profile_id = self.get_id_by_username(profile)
|
||||||
"++++++has_next_page%0A"
|
resp = tmpsession.get('https://www.instagram.com/graphql/query/',
|
||||||
"++++%7D%2C%0A"
|
params={'query_id': 17851374694183129,
|
||||||
"++++nodes+%7B%0A"
|
'variables': '{"id":"' + str(profile_id) + '","first":500}'})
|
||||||
"++++++id%2C%0A"
|
|
||||||
"++++++full_name%2C%0A"
|
|
||||||
"++++++username%2C%0A"
|
|
||||||
"++++++followed_by+%7B%0A"
|
|
||||||
"++++++++count%0A"
|
|
||||||
"++++++%7D%0A"
|
|
||||||
"++++%7D%0A"
|
|
||||||
"++%7D%0A"
|
|
||||||
"%7D%0A"
|
|
||||||
"&ref=relationships%3A%3Afollow_list"]
|
|
||||||
tmpsession.headers.update(self.default_http_header())
|
|
||||||
tmpsession.headers.update({'Referer': 'https://www.instagram.com/' + profile + '/following/'})
|
|
||||||
tmpsession.headers.update({'Content-Type': 'application/x-www-form-urlencoded'})
|
|
||||||
resp = tmpsession.post('https://www.instagram.com/query/', data=query[0] + "first(" + query[1])
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
data = json.loads(resp.text)
|
data = resp.json()
|
||||||
followees = []
|
followers = []
|
||||||
while True:
|
while True:
|
||||||
for followee in data['follows']['nodes']:
|
edge_followed_by = data['data']['user']['edge_followed_by']
|
||||||
followee['follower_count'] = followee.pop('followed_by')['count']
|
followers.extend([follower['node'] for follower in edge_followed_by['edges']])
|
||||||
followees = followees + [followee]
|
page_info = edge_followed_by['page_info']
|
||||||
if data['follows']['page_info']['has_next_page']:
|
if page_info['has_next_page']:
|
||||||
resp = tmpsession.post('https://www.instagram.com/query/',
|
resp = tmpsession.get('https://www.instagram.com/graphql/query/',
|
||||||
data="{0}after({1}%2C+{2}".format(query[0],
|
params={'query_id': 17851374694183129,
|
||||||
data['follows']['page_info']['end_cursor'],
|
'variables': '{"id":"' + str(profile_id) + '","first":500},"after":"' +
|
||||||
query[1]))
|
page_info['end_cursor'] + '"}'})
|
||||||
data = json.loads(resp.text)
|
data = resp.json()
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
return followees
|
else:
|
||||||
if self.test_login(tmpsession):
|
raise ConnectionException("ConnectionError({0}): unable to gather followers.".format(resp.status_code))
|
||||||
raise ConnectionException("ConnectionError(" + str(resp.status_code) + "): "
|
return followers
|
||||||
"unable to gather followees.")
|
|
||||||
raise LoginRequiredException("Login required to gather followees.")
|
def get_followees(self, profile: str) -> List[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
Retrieve list of followees (followings) of given profile.
|
||||||
|
To use this, one needs to be logged in and private profiles has to be followed,
|
||||||
|
otherwise this returns an empty list.
|
||||||
|
|
||||||
|
:param profile: Name of profile to lookup followers.
|
||||||
|
:return: List of followees (list of dictionaries).
|
||||||
|
"""
|
||||||
|
tmpsession = copy_session(self.session)
|
||||||
|
header = self.default_http_header(empty_session_only=True)
|
||||||
|
del header['Connection']
|
||||||
|
del header['Content-Length']
|
||||||
|
header['authority'] = 'www.instagram.com'
|
||||||
|
header['scheme'] = 'https'
|
||||||
|
header['accept'] = '*/*'
|
||||||
|
header['referer'] = 'https://www.instagram.com/' + profile + '/'
|
||||||
|
tmpsession.headers = header
|
||||||
|
profile_id = self.get_id_by_username(profile)
|
||||||
|
resp = tmpsession.get('https://www.instagram.com/graphql/query/',
|
||||||
|
params={'query_id': 17874545323001329,
|
||||||
|
'variables': '{"id":"' + str(profile_id) + '","first":500}'})
|
||||||
|
if resp.status_code == 200:
|
||||||
|
data = resp.json()
|
||||||
|
followees = []
|
||||||
|
while True:
|
||||||
|
edge_follow = data['data']['user']['edge_follow']
|
||||||
|
followees.extend([followee['node'] for followee in edge_follow['edges']])
|
||||||
|
page_info = edge_follow['page_info']
|
||||||
|
if page_info['has_next_page']:
|
||||||
|
resp = tmpsession.get('https://www.instagram.com/graphql/query/',
|
||||||
|
params={'query_id': 17874545323001329,
|
||||||
|
'variables': '{"id":"' + str(profile_id) + '","first":500},"after":"' +
|
||||||
|
page_info['end_cursor'] + '"}'})
|
||||||
|
data = resp.json()
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise ConnectionException("ConnectionError({0}): unable to gather followees.".format(resp.status_code))
|
||||||
|
return followees
|
||||||
|
|
||||||
def download_pic(self, name: str, url: str, date_epoch: float, outputlabel: Optional[str] = None,
|
def download_pic(self, name: str, url: str, date_epoch: float, outputlabel: Optional[str] = None,
|
||||||
filename_suffix: Optional[str] = None) -> bool:
|
filename_suffix: Optional[str] = None) -> bool:
|
||||||
|
Loading…
Reference in New Issue
Block a user