Skip to content

Instantly share code, notes, and snippets.

@dschep
Last active January 1, 2022 03:16
Show Gist options
  • Select an option

  • Save dschep/28bf9848d76d4790df1330a246cc90cc to your computer and use it in GitHub Desktop.

Select an option

Save dschep/28bf9848d76d4790df1330a246cc90cc to your computer and use it in GitHub Desktop.
Instagram Top 9 - example output: https://www.instagram.com/p/B6vVp93Bb5F/
"""
An Instagram Top 9 generator that doesn't require connecting your account
to an untrustworthy 3rd party Instagram app.
Install the requirements with `pip3 install igramscraper Pillow click`
then run `python3 top9.py`
When done, you will have a YOURUSERNAME-top9.jpg in your working directory.
"""
from datetime import datetime
from igramscraper.instagram import Instagram
from PIL import Image
import click
import requests
instagram = Instagram()
@click.command()
@click.option(
"--user",
prompt="Your Instagram account (without @)",
help="The instagram username to create a top 9 for",
)
@click.option(
"--login-user",
help="The instagram username to login with. Doesn't log in if omitted.",
)
@click.option(
"--tfa",
help="Use two factor auth during login",
)
def top9(user, tfa=False, login_user=None):
if login_user:
password = click.prompt("Your Instagram password")
instagram.with_credentials(login_user, password)
instagram.login(two_step_verificator=tfa)
now = datetime.utcnow()
if now.month > 7:
this_year = now.year
else:
this_year = now.year - 1
posts = None
count = 0
prev = None
while (
posts is None
or datetime.fromtimestamp(posts[-1].created_time).year >= this_year
):
count += 50
posts = instagram.get_medias(user, count)
last = datetime.fromtimestamp(posts[-1].created_time)
if prev == last:
break
prev = last
this_year_photos = [
post
for post in posts
if datetime.fromtimestamp(post.created_time).year == this_year
and post.type in (post.TYPE_IMAGE, post.TYPE_SIDECAR)
]
top9 = sorted(this_year_photos, key=lambda post: -post.likes_count)[:9]
img = Image.new("RGB", (1080, 1080))
for i, post in enumerate(top9):
tile = Image.open(requests.get(post.image_high_resolution_url, stream=True).raw)
if tile.size[0] > tile.size[1]:
tile = tile.crop(
(
(tile.size[0] - tile.size[1]) / 2,
0,
(tile.size[0] - tile.size[1]) / 2 + tile.size[1],
tile.size[1],
)
)
elif tile.size[0] < tile.size[1]:
tile = tile.crop(
(
0,
(tile.size[1] - tile.size[0]) / 2,
tile.size[0],
(tile.size[1] - tile.size[0]) / 2 + tile.size[0],
)
)
tile = tile.resize((360, 360), Image.ANTIALIAS)
print(f"{post.likes_count} likes - {post.link}")
img.paste(tile, (i % 3 * 360, i // 3 * 360))
img.save(f"{user}-top9.jpg")
if __name__ == "__main__":
top9()
@raenb0

raenb0 commented Dec 31, 2019

Copy link
Copy Markdown

I got this error, any thoughts? (I'm a total newbie to python)
ERROR: igramscraper 0.3.2 has requirement requests==2.21.0, but you'll have requests 2.22.0 which is incompatible.

@dschep

dschep commented Dec 31, 2019

Copy link
Copy Markdown
Author

good catch @raenb0. run pip3 install igramscraper Pillow click instead.

@ahjota

ahjota commented Jan 1, 2020

Copy link
Copy Markdown

Had some fun with shell not being able to parse my pw, so I added

@click.option(
    "--password",
    prompt="Your IG password",
    hide_input=True,
    help="The password for the instagram account; Only needed if it is private",
)

Also -- removing the post.type filter lets you pull multi-image posts (sidecars) and videos as well. :)

and post.type == post.TYPE_IMAGE

Good stuff!

@dschep

dschep commented Jan 1, 2020

Copy link
Copy Markdown
Author

@ahjota, yeah, probably not the best idea to put your password in your shell history anyway :) Updated the gist! :shipit:

Also -- removing the post.type filter lets you pull multi-image posts (sidecars) and videos as well. :)

and post.type == post.TYPE_IMAGE

ah, didn't think of mutlimage, but I figured video probably wouldn't be that useful tho.

@raenb0

raenb0 commented Jan 2, 2020

Copy link
Copy Markdown

Can I ask a dumb python question? In the script, where exactly do I put my username and pwd? Anywhere there are quotation marks, or only after "prompt", or...?

@ahjota

ahjota commented Jan 3, 2020

Copy link
Copy Markdown

@raenb0 If you follow the instructions at the very top of the script, (install igramscraper and then run) then you can enter in your username and password when it asks you. :)

@dschep

dschep commented Jan 3, 2020

Copy link
Copy Markdown
Author

Yup, run the script with no arguments. I've updated the gist work @ahjota's suggestions so it'll ask you for both your username and password

@raenb0

raenb0 commented Jan 3, 2020 via email

Copy link
Copy Markdown

@dschep

dschep commented Jan 3, 2020

Copy link
Copy Markdown
Author

Huh, that's odd. I don't think there's any issue with conemu. If you're using python3 top9.py maybe try the pip install as python3 -m pip install igramscraper Pillow click. But it's still very odd that it does nothing. I'd expect at least an error πŸ€”

@raenb0

raenb0 commented Jan 4, 2020 via email

Copy link
Copy Markdown

@dschep

dschep commented Dec 29, 2020

Copy link
Copy Markdown
Author

@dschep

dschep commented Dec 29, 2020

Copy link
Copy Markdown
Author

Oops, actually still works fine without login, but bc of the change from @ahota, you couldn't actually not login. I've changed it so that password is only by prompt, and you specify the desire to login by using the --login-user flag.

@mlisdev

mlisdev commented Aug 16, 2021

Copy link
Copy Markdown

Just doing a 2021 check in to say: Still works!

Is it weird that I used this to test my terminal was working on an old computer? probably. sorry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment