Instaloader, get n most recent posts

1.1k Views Asked by At

Currently, the below code returns all the posts from the profile:

profilename = 'oneplus'
loader = instaloader.Instaloader()    
profile = Profile.from_username(loader.context,profilename)
posts = profile.get_posts()

If the profile has, say 3000 posts, it takes a lot of time to load for instaloader.

However, I just want most recent n posts, and n<10, how do I do that?

3

There are 3 best solutions below

0
On

finally came across something handy!

Firstly:

pip install func_timeout

Imagine your function was:

def sum(x,y): 
    return x+y

Then use it like so:

from func_timeout import func_timeout, FunctionTimedOut

try:
    seconds = 5 # times out after 5 secs
    result=func_timeout(seconds,sum,args=(5,3))
except FunctionTimedOut:
    print('timeout')
except Exception as e:
    print(e)

For me, it works like a charm.

Note: if you are thinking of downloading the posts, make sure you also timeout control the download function, as the function scans all the comments, which can get pretty lengthy.

If in trouble, visit the website where I found it: https://pypi.org/project/func-timeout/

Cheers

0
On

I figured it out:

posts = profile.get_posts()

doesn't actually take so much time, it returns an iterable generator object and then when you try to do:

list(posts)

this is what takes so much time. So what I did is:

counter=0
n=20
first_n_posts =[]
for post in posts:
    first_n_posts.append(post)
    counter+=1
    if counter >= n:
        break
for post in first_n_posts:
    print(post.likes)

which takes less than a second for me.

Also, be aware that the stuff you do before can take some time as well:

  • the login process took me like 5 seconds: loader = instaloader.Instaloader() loader.login(username, 'password')

  • loading a profile another 7 seconds:

      profile_target = instaloader.Profile.from_username(loader.context, profile_username)
    

so loading the 20 posts from account with thousands of posts took like 15 seconds total

0
On

Calling __next__() only loads one instaloader.Post object per call which is a lot faster than using something like n_posts = [i for i in posts][:n] where all instaloader.Post objects are loaded.

profilename = 'oneplus'
loader = instaloader.Instaloader()    
profile = Profile.from_username(loader.context,profilename)
posts = profile.get_posts()

n = 5
n_posts = [posts.__next__() for i in range(n)]

# n_posts is a list containing instaloader.Post objects
# The post objects are the n most recent posts from the given profile. 
# The order of these post objects are recent -> older