📷 Instagram Bot - Like/Comment/Follow Automation Script
Clone or download
timgrossmann Merge pull request #3145 from timgrossmann/bugfix/post_count
applying @sionkings proposal about getting post count
Latest commit 9cef731 Oct 15, 2018
Permalink
Failed to load latest commit information.
.github Update issue_template.md Nov 5, 2017
assets Update business_categories.md Oct 11, 2018
docker_conf Replaced deprecated feature with new in sample quickstart scripts Apr 20, 2018
docs Updated recommendations of versions of chromium and chromedriver Sep 28, 2018
extensions adds extensions as a package folder Dec 4, 2017
icons Add Quota Supervisor & lots of revisions Aug 25, 2018
instapy Merge pull request #3145 from timgrossmann/bugfix/post_count Oct 15, 2018
logs Revert "Merge pull request #1313 from davegallant/master" Jan 31, 2018
quickstart_templates restored repo Sep 29, 2018
scripts Update chromedriver to the latest stable version (#1092) Dec 13, 2017
tests UPDATED - test file Aug 4, 2018
.dockerignore Removed /requirements.txt from dockerignore Sep 18, 2017
.gitignore Updates to instapy.py and clarifai_util.py to improve working with Cl… Oct 11, 2018
.travis.yml Use Travis CI to run flake8 tests on pull requests Oct 4, 2017
CODE_OF_CONDUCT.md Create CODE_OF_CONDUCT.md Oct 27, 2017
LICENSE change license to GPLv3 Aug 21, 2018
MANIFEST.in Upgrade `setup()` meta-data & revise `requirements.txt` for better Py… Aug 28, 2018
README.md Added parameter for setting probability Oct 13, 2018
api.json Documented api in machine readable JSON Jul 13, 2018
docker-allinone.yml Revert "Merge pull request #1313 from davegallant/master" Jan 31, 2018
docker-compose.yml Revert "Merge pull request #1313 from davegallant/master" Jan 31, 2018
docker-dev.yml Revert "Merge pull request #1313 from davegallant/master" Jan 31, 2018
docker-prod.yml Revert "Merge pull request #1313 from davegallant/master" Jan 31, 2018
docker-swarm.yml Add link to recipe Apr 17, 2018
docker_quickstart.py Replaced deprecated feature with new in sample quickstart scripts Apr 20, 2018
proxy_extension.py applied proposed change Jun 13, 2018
quickstart.py modify minimal quickstart file Sep 26, 2018
requirements.txt Small bug fixes in `setup()` and update requirements Aug 28, 2018
setup.py Small bug fixes in `setup()` and update requirements Aug 28, 2018
wait-for-selenium.sh Added waiting for selenium to start on port 4444 Sep 20, 2017

README.md

InstaPy

MIT license built with Selenium built with Python3 Travis

Automation Script for “farming” Likes, Comments and Followers on Instagram

Implemented in Python using the Selenium module.

Think this tool is worth supporting? Head over to https://github.com/timgrossmann/InstaPy/wiki/How-to-Contribute to find out how you can help. Become a part of InstaPy!

Have an issue? Head over to https://github.com/timgrossmann/InstaPy/wiki/Reporting-An-Issue to find out how to report this to us and get help.

Disclaimer: Please Note that this is a research project. I am by no means responsible for any usage of this tool. Use on your own behalf. I’m also not responsible if your accounts get banned due to extensive use of this tool.

Newsletter: SignUp for the Newsletter here!

Social

Slack Workspace | InstaPy TwitterMy Twitter | How it works (Medium) | Check out the talk |

Listen to the "Talk Python to me"-Episode | Support InstaPy!

paypal

Table of Contents

Getting started

Video tutorials:

Setting up InstaPy for OSX

Setting up InstaPy at Digital Ocean (for Debian)

Guides:

How to Ubuntu (64-Bit)       

How to RaspberryPi       

How to Windows

Basic Installation:

1. git clone https://github.com/timgrossmann/InstaPy.git
2. cd InstaPy
3. pip install .
or
3. python setup.py install
  1. Download chromedriver for your system from here. Extract the .zip file and put it in /assets folder.

Preferred Installation:

The best way to install InstaPy is to create a virtualenv, install InstaPy there and run it from a separate file:

1. virtualenv venv
2. source venv/bin/activate
3. pip install git+https://github.com/timgrossmann/InstaPy.git

If you're not familiar with virtualenv, please read about it here and use it to your advantage. In essence, this is be the only Python library you should install as root (e.g., with sudo). All other Python libraries should be inside a virtualenv. Now copy/paste the quickstart.py Python code below and run your first InstaPy script. Remember to run it with Python from the virtualenv, so from venv/bin/python. To make sure which Python is used, run which python, it will tell you which Python is 'active'. Running source venv/bin/activate will activate the correct Python to run InstaPy. To exit an activated virtualenv run `deactivate'.

Set it up yourself with this Basic Setup

Basic setup is a good way to test the tool. At project root folder open quickstart.py and update with your username and password.

from instapy import InstaPy
from instapy.util import smart_run



# login credentials
insta_username = ''
insta_password = ''

# get an InstaPy session!
# set headless_browser=True to run InstaPy in the background
session = InstaPy(username=insta_username,
                  password=insta_password,
                  headless_browser=False)


with smart_run(session):
    """ Activity flow """
    # settings
    session.set_relationship_bounds(enabled=True,
                                      delimit_by_numbers=True,
                                       max_followers=4590,
                                        min_followers=45,
                                        min_following=77)
    
    session.set_dont_include(["friend1", "friend2", "friend3"])
    session.set_dont_like(["pizza", "#store"])
    
    
    # actions
    session.like_by_tags(["natgeo"], amount=10)

Execute it:

$ python quickstart.py

Or use our GUI

1. Cross Platform GUI

2. Session scheduling with Telegram

3. InstaPy-Light, a light version of InstaPy

InstaPy Available Features

Commenting

# default enabled=False, ~ every 4th image will be commented on

session.set_do_comment(enabled=True, percentage=25)
session.set_comments(['Awesome', 'Really Cool', 'I like your stuff'])

# you can also set comments for specific media types (Photo / Video)

session.set_comments(['Nice shot!'], media='Photo')
session.set_comments(['Great Video!'], media='Video')

# and you can add the username of the poster to the comment by using

session.set_comments(['Nice shot! @{}'], media='Photo')

Following

# default enabled=False, follows ~ 10% of the users from the images, times=1
# (only follows a user once (if unfollowed again))

session.set_do_follow(enabled=True, percentage=10, times=2)

Following by a list

This will follow each account from a list of instagram nicknames
follow_by_list(followlist=['samantha3', 'larry_ok'], times=1, sleep_delay=600, interact=False)

only follows a user once (if unfollowed again) would be useful for the precise targeting
sleep_delay is used to define break time after some good following (averagely ~10 follows)
For example, if one needs to get followbacks from followers of a chosen account/group of accounts.

accs = ['therock','natgeo']
session.follow_by_list(accs, times=1, sleep_delay=600, interact=False)
  • You can also interact with the followed users by enabling interact=True which will use the configuration of set_user_interact setting:
session.set_user_interact(amount=4,
				 percentage=50,
                  randomize=True,
                   media='Photo')
session.follow_by_list(followlist=['samantha3', 'larry_ok'], times=2, sleep_delay=600, interact=True)

Follow someone else's followers

# Follows the followers of each given user
# The usernames can be either a list or a string
# The amount is for each account, in this case 30 users will be followed
# If randomize is false it will pick in a top-down fashion

session.follow_user_followers(['friend1', 'friend2', 'friend3'], amount=10, randomize=False)

# default sleep_delay=600 (10min) for every 10 user following, in this case
# sleep for 60 seconds

session.follow_user_followers(['friend1', 'friend2', 'friend3'], amount=10, randomize=False, sleep_delay=60)

Note: simulation takes place while running this feature.

Follow users that someone else is following

# Follows the people that a given users are following
# The usernames can be either a list or a string
# The amount is for each account, in this case 30 users will be followed
# If randomize is false it will pick in a top-down fashion

session.follow_user_following(['friend1', 'friend2', 'friend3'], amount=10, randomize=False)

# default sleep_delay=600 (10min) for every 10 user following, in this case
# sleep for 60 seconds

session.follow_user_following(['friend1', 'friend2', 'friend3'], amount=10, randomize=False, sleep_delay=60)

Note: simulation takes place while running this feature.

Follow someone else's followers/following

# For 50% of the 30 newly followed, move to their profile
# and randomly choose 5 pictures to be liked.
# Take into account the other set options like the comment rate
# and the filtering for inappropriate words or users

session.set_user_interact(amount=5, randomize=True, percentage=50, media='Photo')
session.follow_user_followers(['friend1', 'friend2', 'friend3'], amount=10, randomize=False, interact=True)

Follow by Tags

# Follow user based on hashtags (without liking the image)

session.follow_by_tags(['tag1', 'tag2'], amount=10)

Follow the likers of photos of users

This will follow the people those liked photos of given list of users
session.follow_likers (['user1' , 'user2'], photos_grab_amount = 2, follow_likers_per_photo = 3, randomize=True, sleep_delay=600, interact=False)

in this case 2 random photos from each given user will be analyzed and 3 people who liked them will be followed, so 6 follows in total
The usernames can be any list
The photos_grab_amount is how many photos will I grat from users profile and analyze who liked it
The follow_likers_per_photo is how many people to follow per each photo
randomize=False will take photos from newes, true will take random from first 12
sleep_delay is used to define break time after some good following (averagely ~10 follows)

  • You can also interact with the followed users by enabling interact=True which will use the configuration of set_user_interact setting:
session.set_user_interact(amount=2,
				 percentage=70,
                  randomize=True,
                   media='Photo')
session.follow_likers (['user1' , 'user2'], photos_grab_amount = 2, follow_likers_per_photo = 3, randomize=True, sleep_delay=600, interact=True)

Follow the commenters of photos of users

This will follow the people those commented on photos of given list of users
session.follow_commenters(['user1', 'user2', 'user3'], amount=100, daysold=365, max_pic = 100, sleep_delay=600, interact=False)

in this case (max 100 newest photos & maximum 365 days old) from each given user will be analyzed and 100 people who commented the most will be followed
The usernames can be any list
The amount is how many people to follow
The daysold will only take commenters from photos no older than daysold days
The max_pic will limit number of photos to analyze
sleep_delay is used to define break time after some good following (averagely ~10 follows)

  • You can also interact with the followed users by enabling interact=True which will use the configuration of set_user_interact setting:
session.set_user_interact(amount=3,
				 percentage=32,
                  randomize=True,
                   media='Video')
session.follow_commenters(['user1', 'user2', 'user3'], amount=100, daysold=365, max_pic = 100, sleep_delay=600, interact=True)

Interact with specific users

# Interact with specific users
# set_do_like, set_do_comment, set_do_follow are applicable

session.set_do_follow(enabled=False, percentage=50)
session.set_comments(["Cool", "Super!"])
session.set_do_comment(enabled=True, percentage=80)
session.set_do_like(True, percentage=70)
session.interact_by_users(['user1', 'user2', 'user3'], amount=5, randomize=True, media='Photo')

Interact with users that someone else is following

# Interact with the people that a given user is following
# set_do_comment, set_do_follow and set_do_like are applicable

session.set_user_interact(amount=5, randomize=True, percentage=50, media='Photo')
session.set_do_follow(enabled=False, percentage=70)
session.set_do_like(enabled=False, percentage=70)
session.set_comments(["Cool", "Super!"])
session.set_do_comment(enabled=True, percentage=80)
session.interact_user_following(['natgeo'], amount=10, randomize=True)

Note: simulation takes place while running this feature.

Interact with someone else's followers

# Interact with the people that a given user is followed by
# set_do_comment, set_do_follow and set_do_like are applicable

session.set_user_interact(amount=5, randomize=True, percentage=50, media='Photo')
session.set_do_follow(enabled=False, percentage=70)
session.set_do_like(enabled=False, percentage=70)
session.set_comments(["Cool", "Super!"])
session.set_do_comment(enabled=True, percentage=80)
session.interact_user_followers(['natgeo'], amount=10, randomize=True)

Note: simulation takes place while running this feature.

Interact on posts at given URLs

Like, comment, follow on the post in the links provided, also can interact the owner of the post
session.interact_by_URL(urls=["some/URL/1", "some/URL/2" "other/URL"], randomize=True, interact=True)

To use, define all of the interaction settings and start the feature right away!

#define interaction settings
session.set_do_like(enabled=True, percentage=94)
session.set_do_comment(enabled=True, percentage=24)
session.set_comments(["Masterful shot", "Chilling!", "Unbelievably great..."])
session.set_do_follow(enabled=True, percentage=44)
session.set_user_interact(amount=6, randomize=True, percentage=72, media='Photo')

#start the feature
session.interact_by_URL(urls=["Fv0J4AJ3Y7r/?taken-at=628416252", "Vb0D4bJgY7r" "Dj0J4VJgY7r"], randomize=True, interact=True)
Parameters:

urls:
Contains the URLs of the posts to be interacted.

  • You can provide URLs in these formats:
    full: "https://www.IG.com/p/Aj0J4bJDY7r/?taken-at=128316221"
    just post link: "https://www.IG.com/p/Aj0J4bJDY7r/"
    just post handle: "Aj0J4bJDY7r/?taken-at=128316221"
    just post ID: "Aj0J4bJDY7r"

randomize:
Shuffles the order of the URLs in the given list before starts to interact.

interact:
Use it if you like to also interact the post owner after doing interactions on the post itself.

Unfollowing

Unfollows the accounts you're following

It will unfollow ~10 accounts and sleep for ~10 minutes and then will continue to unfollow...

There are 4 Unfollow methods available to use:

|> customList |> InstapyFollowed |> nonFollowers |> allFollowing

1 - Unfollow specific users from a CUSTOM list (has 2 tracks- "all" and "nonfollowers"):
when track is "all", it will unfollow all of the users in a given list;

custom_list = ["user_1", "user_2", "user_49", "user332", "user50921", "user_n"]
session.unfollow_users(amount=84, customList=(True, custom_list, "all"), style="RANDOM", unfollow_after=55*60*60, sleep_delay=600)

if track is "nonfollowers", it will unfollow all of the users in a given list WHO are not following you back;

custom_list = ["user_1", "user_2", "user_49", "user332", "user50921", "user_n"]
session.unfollow_users(amount=84, customList=(True, custom_list, "nonfollowers"), style="RANDOM", unfollow_after=55*60*60, sleep_delay=600)
  • PRO: customList method can any kind of iterable container, such as list, tuple or set.

2 - Unfollow the users WHO was followed by InstaPy (has 2 tracks- "all" and "nonfollowers"):
again, if you like to unfollow all of the users followed by InstaPy, use the track- "all";

session.unfollow_users(amount=60, InstapyFollowed=(True, "all"), style="FIFO", unfollow_after=90*60*60, sleep_delay=501)

but if you like you unfollow only the users followed by InstaPy WHO do not follow you back, use the track- "nonfollowers";

session.unfollow_users(amount=60, InstapyFollowed=(True, "nonfollowers"), style="FIFO", unfollow_after=90*60*60, sleep_delay=501)

3 - Unfollow the users WHO do not follow you back:

session.unfollow_users(amount=126, nonFollowers=True, style="RANDOM", unfollow_after=42*60*60, sleep_delay=655)

4 - Just unfollow, regardless of a user follows you or not:

session.unfollow_users(amount=40, allFollowing=True, style="LIFO", unfollow_after=3*60*60, sleep_delay=450)

Parameters (all of these parameters apply to all of the 4 methods available):

style
You can choose unfollow style as "FIFO" (First-Input-First-Output) OR "LIFO" (Last-Input-First-Output) OR "RANDOM".

  • with "FIFO", it will unfollow users in the exact order they are loaded ("FIFO" is the default style unless you change it);
  • with "LIFO" it will unfollow users in the reverse order they were loaded;
  • with "RANDOM" it will unfollow users in the shuffled order;

unfollow_after
By using this, you can unfollow users only after following them certain amount of time.
it will help to provide seamless unfollow activity without the notice of the target user
To use it, just add unfollow_after parameter with the desired time interval, e.g.,

session.unfollow_users(amount=94, InstapyFollowed=(True, "all"), style="RANDOM", unfollow_after=48*60*60, sleep_delay=600)

will unfollow users only after following them 48 hours (2 days).

  • Since unfollow_afters value is in seconds, you can simply give it unfollow_after=3600 to unfollow after 3600 seconds.
    Yeah, values kind of 1*60*60- which is also equal to 1 hour or 3600 seconds, is much more easier to use.

Sure if you like to not use it, give the value of None- unfollow_after=None.

sleep_delay
Sleep delay sets the time it will sleep after every ~10 unfollows (default delay is ~10 minutes).

NOTE: You should know that, in one RUN, unfollow_users feature can take only one method from all 4 above.
That's why, it is best to disable other 3 methods while using a one:

session.unfollow_users(amount=200, customList=(True, ["user1", "user2", "user88", "user200"], "all"), InstapyFollowed=(False, "all"), nonFollowers=False, allFollowing=False, style="FIFO", unfollow_after=22*60*60, sleep_delay=600)

here the unfollow method- customList is used
OR just keep the method you want to use and remove other 3 methods from the feature

session.unfollow_users(amount=200, allFollowing=True, style="FIFO", unfollow_after=22*60*60, sleep_delay=600)

here the unfollow method- alFollowing is used

Don't unfollow active users

# Prevents unfollow followers who have liked one of your latest 5 posts

session.set_dont_unfollow_active_users(enabled=True, posts=5)

Interactions based on the number of followers and/or following a user has

This is used to check the number of followers and/or following a user has and if these numbers either exceed the number set OR does not pass the number set OR if their ratio does not reach desired potency ratio then no further interaction happens
session.set_relationship_bounds(enabled=True,
				 potency_ratio=1.34,
				  delimit_by_numbers=True,
				   max_followers=8500,
				    max_following=4490,
				     min_followers=100,
				      min_following=56,
				       min_posts=10,
                                        max_posts=1000)

Use enabled=True to activate this feature, and enabled=False to deactivate it, any time
delimit_by_numbers is used to activate & deactivate the usage of max & min values
potency_ratio accepts values in 2 formats according to your style: positive & negative

  • potency_ratio with POSITIVE values can be used to route interactions to only potential (real) users WHOSE followers count is higher than following count (e.g., potency_ratio = 1.39)
    find desired potency_ratio with this formula: potency_ratio == followers count / following count (use desired counts)

e.g., target user has 5000 followers & 4000 following and you set potency_ratio=1.35.
Now it will not interact with this user, cos the user's relationship ratio is 5000/4000==1.25 and 1.25 is below desired potency_ratio of 1.35

  • potency_ratio with NEGATIVE values can be used to route interactions to only massive followers WHOSE following count is higher than followers count (e.g., potency_ratio = -1.42)
    find desired potency_ratio with this formula: potency_ratio == following count / followers count (use desired counts)

e.g., target user has 2000 followers & 3000 following and you set potency_ratio = -1.7.
Now it will not interact with this user, cos the user's relationship ratio is 3000/2000==1.5 and 1.5 is below desired potency_ratio of 1.7 (note that, negative - sign is only used to determine your style, nothing more)

There are 3 COMBINATIONS available to use:
  • 1. You can use potency_ratio or not (e.g., potency_ratio=None, delimit_by_numbers=True) - will decide only by your pre-defined max & min values regardless of the potency_ratio
session.set_relationship_bounds (enabled=True, potency_ratio=None, delimit_by_numbers=True, max_followers=22668, max_following=10200, min_followers=400, min_following=240)
  • 2. You can use only potency_ratio (e.g., potency_ratio=-1.5, delimit_by_numbers=False) - will decide per potency_ratio regardless of the pre-defined max & min values
session.set_relationship_bounds (enabled=True, potency_ratio=-1.5, delimit_by_numbers=False, max_followers=400701, max_following=90004, min_followers=963, min_following=2310)

apparently, once delimit_by_numbers gets False value, max & min values do not matter

  • 3. You can use both potency_ratio and pre-defined max & min values together (e.g., potency_ratio=2.35, delimit_by_numbers=True) - will decide per potency_ratio & your pre-defined max & min values
session.set_relationship_bounds (enabled=True, potency_ratio=2.35, delimit_by_numbers=True, max_followers=10005, max_following=24200, min_followers=77, min_following=500)

All of the 4 max & min values are able to freely operate, e.g., you may want to only delimit max_followers and min_following (e.g., max_followers=52639, max_following=None, min_followers=None, min_following=2240)

session.set_relationship_bounds (enabled=True, potency_ratio=-1.44, delimit_by_numbers=True, max_followers=52639, max_following=None, min_followers=None, min_following=2240)

Interactions based on the number of posts a user has

This is used to check number of posts of a user and skip if they aren't in the boundaries provided

session.set_relationship_bounds(min_posts=10,
                                 max_posts=1000)

Users that have more than 1000 posts or less than 10 will be discarded

N.B.: It is up to the user to check that min_posts < max_posts

You can also set only one parameter at a time:

session.set_relationship_bounds(max_posts=1000)

Will skip only users that have more than 1000 posts in their feed

Skipping user for private account, no profile picture, business account

This is used to skip users with certain condition

session.set_skip_users(skip_private=True,
                       private_percentage=100,
                       skip_no_profile_pic=False,
                       no_profile_pic_percentage=100,
                       skip_business=False,
                       business_percentage=100,
                       skip_business_categories=[],
                       dont_skip_business_categories=[])
Skip private account

This is done by default

session.set_skip_users(skip_private=True,
                       private_percentage=100)

Will skip users that have private account, even if are followed by running account. You can set a percentage of skipping: private_percentage= 100 always skip private users private_percentage= 0 never skip private users (so set skip_private=False)

Skip users that don't have profile picture
session.set_skip_users(skip_private=True,
                       skip_no_profile_pic=True,
                       no_profile_pic_percentage=100)

Will skip users that haven't uploaded yet a profile picture You can set a percentage of skipping: no_profile_pic_percentage= 100 always skip users without profile picture no_profile_pic_percentage= 0 never skip users without profile picture (so set skip_no_profile_pic=False)

Skip users that have business account
session.set_skip_users(skip_private=True,
                       skip_no_profile_pic=True,
		               skip_business=True,
		               business_percentage=100)

This will skip all users that have business account activated. You can set a percentage of skipping: business_percentage= 100 always skip business users business_percentage= 0 never skip business users (so set skip_business=False)

N.B.: This business_percentage parameter works only if no skip_business_categories or dont_skip_business_categories are provided!

Skip only users that have certain business account
session.set_skip_users(skip_private=True,
                       skip_no_profile_pic=True,
		       skip_business=True,
		       skip_business_categories=['Creators & Celebrities'])

This will skip all business accounts that have category in given list N.B. In skip_business_categories you can add more than one category

Skip all business accounts, except from list given
session.set_skip_users(skip_private=True,
                       skip_no_profile_pic=True,
		       skip_business=True,
		       dont_skip_business_categories=['Creators & Celebrities'])

This will skip all business accounts except the ones that have a category that matches one item in the list of dont_skip_business_categories N.B. If both dont_skip_business_categories and skip_business_categories, InstaPy will skip only business accounts in the list given from skip_business_categories.

A list of all availlable business categories can be found here

Liking based on the number of existing likes a post has

This is used to check the number of existing likes a post has and if it either exceed the maximum value set OR does not pass the minimum value set then it will not like that post
session.set_delimit_liking(enabled=True, max=1005, min=20)

Use enabled=True to activate and enabled=False to deactivate it, any time
max is the maximum number of likes to compare
min is the minimum number of likes to compare

You can use both max & min values OR one of them as you desire, just put the value of None to the one you don't want to check for., e.g.,

session.set_delimit_liking(enabled=True, max=242, min=None)

at this configuration above, it will not check number of the existing likes against minimum value

  • Example:
session.set_delimit_liking(enabled=True, max=500, min=7)

Now, if a post has more existing likes than maximum value of 500, then it will not like that post, similarly, if that post has less existing likes than the minimum value of 7, then it will not like that post...

Commenting based on the number of existing comments a post has

This is used to check the number of existing comments a post has and if it either exceed the maximum value set OR does not pass the minimum value set then it will not comment on that post
session.set_delimit_commenting(enabled=True, max=32, min=0)

Use enabled=True to activate and enabled=False to deactivate it, any time
max is the maximum number of comments to compare
min is the minimum number of comments to compare

You can use both max & min values OR one of them as you desire, just leave it out or put it to None to the one you don't want to check for., e.g.,

session.set_delimit_commenting(enabled=True, min=4)
# or
session.set_delimit_commenting(enabled=True, max=None, min=4)

at this configuration above, it will not check number of the existing comments against maximum value

  • Example:
session.set_delimit_commenting(enabled=True, max=70, min=5)

Now, if a post has more comments than the maximum value of 70, then it will not comment on that post, similarly, if that post has less comments than the minimum value of 5, then it will not comment on that post...

Commenting based on madatory words in the description or first comment

This is used to check the description of the post and the first comment of the post (some users only put tags in the comments instead of the post description) for the occurence of mandatory words before commenting. If none of the mandatory words is present, the post will not be commented.

This feature is helpful when you want to comment only on specific tags.

session.set_delimit_commenting(enabled=True, comments_mandatory_words=['cat', 'dog'])

This will only comment on posts that contain either cat or dog in the post description or first comment.

Comment by Locations

session.comment_by_locations(['224442573/salton-sea/'], amount=100)
# or
session.comment_by_locations(['224442573'], amount=100)
# or include media entities from top posts section

session.comment_by_locations(['224442573'], amount=5, skip_top_posts=False)

This method allows commenting by locations, without liking posts. To get locations follow instructions in 'Like by Locations'

Like by Locations

session.like_by_locations(['224442573/salton-sea/'], amount=100)
# or
session.like_by_locations(['224442573'], amount=100)
# or include media entities from top posts section

session.like_by_locations(['224442573'], amount=5, skip_top_posts=False)

You can find locations for the like_by_locations function by:

Example:

Like by Tags

# Like posts based on hashtags
session.like_by_tags(['natgeo', 'world'], amount=10)

Like by Tags and interact with user

# Like posts based on hashtags and like 3 posts of its poster
session.set_user_interact(amount=3, randomize=True, percentage=100, media='Photo')
session.like_by_tags(['natgeo', 'world'], amount=10, interact=True)

Like by Feeds

# This is used to perform likes on your own feeds
# amount=100  specifies how many total likes you want to perform
# randomize=True randomly skips posts to be liked on your feed
# unfollow=True unfollows the author of a post which was considered
# inappropriate interact=True visits the author's profile page of a
# certain post and likes a given number of his pictures, then returns to feed

session.like_by_feed(amount=100, randomize=True, unfollow=True, interact=True)

Blacklist Campaign

# Controls your interactions by campaigns.
# ex. this week InstaPy will like and comment interacting by campaign called
# 'soccer', next time InstaPy runs, it will not interact again with users in
# blacklist
# In general, this means that once we turn off the soccer_campaign again, InstaPy
# will have no track of the people it interacted with about soccer.
# This will help you target people only once but several times for different campaigns

session.set_blacklist(enabled=True, campaign='soccer_campaign')
session.set_do_comment(True, percentage=50)
session.set_comments(['Neymar is better than CR7', 'Soccer is cool'])
session.like_by_tags(['soccer', 'cr7', 'neymar'], amount=100, media='Photo')

Smart Hashtags

# Generate smart hashtags based on https://displaypurposes.com ranking,
# banned and spammy tags are filtered out.
# (limit) defines amount limit of generated hashtags by hashtag
# (sort) sort generated hashtag list 'top' and 'random' are available
# (log_tags) shows generated hashtags before use it
# (use_smart_hashtags) activates like_by_tag to use smart hashtags

session.set_smart_hashtags(['cycling', 'roadbike'], limit=3, sort='top', log_tags=True)
session.like_by_tags(amount=10, use_smart_hashtags=True)

Mandatory Words

session.set_mandatory_words(['#food', '#instafood'])

.set_mandatory_words searches the description and owner comments for words and will like the image if all of those words are in there

Restricting Likes

session.set_dont_like(['#exactmatch', '[startswith', ']endswith', 'broadmatch'])

.set_dont_like searches the description and owner comments for hashtags and won't like the image if one of those hashtags are in there

You have 4 options to exclude posts from your InstaPy session:

  • words starting with # will match only exact hashtags (e. g. #cat matches #cat, but not #catpic)
  • words starting with [ will match all hashtags starting with your word (e. g. [cat matches #catpic, #caturday and so on)
  • words starting with ] will match all hashtags ending with your word (e. g. ]cat matches #mycat, #instacat and so on)
  • words without these prefixes will match all hashtags that contain your word regardless if it is placed at the beginning, middle or end of the hashtag (e. g. cat will match #cat, #mycat, #caturday, #rainingcatsanddogs and so on)

Ignoring Users

# completely ignore liking images from certain users

session.set_ignore_users(['random_user', 'another_username'])

Ignoring Restrictions

# will ignore the don't like if the description contains
# one of the given words

session.set_ignore_if_contains(['glutenfree', 'french', 'tasty'])

Excluding friends

# will prevent commenting on and unfollowing your good friends (the images will
# still be liked)

session.set_dont_include(['friend1', 'friend2', 'friend3'])

Follow/Unfollow/exclude not working?

If you notice that one or more of the above functionalities are not working as expected - e.g. you have specified:

session.set_do_follow(enabled=True, percentage=10, times=2)

but none of the profiles are being followed - or any such functionality is misbehaving - then one thing you should check is the position/order of such methods in your script. Essentially, all the set_* methods have to be before like_by_tags or like_by_locations or unfollow. This is also implicit in all the exmples and quickstart.py

Bypass Suspicious Login Attempt

If you're having issues with the "we detected an unusual login attempt" message, you can bypass it setting InstaPy in this way:

session = InstaPy(username=insta_username, password=insta_password, bypass_suspicious_attempt=True)

bypass_suspicious_attempt=True will send the verification code to your email, and you will be prompted to enter the security code sent to your email. It will login to your account, now you can set bypass_suspicious_attempt to False bypass_suspicious_attempt=False and InstaPy will quickly login using cookies.

Quota Supervisor

Take full control of the actions with the most sophisticated approaches
session.set_quota_supervisor(enabled=True, sleep_after=["likes", "comments_d", "follows", "unfollows", "server_calls_h"], sleepyhead=True, stochastic_flow=True, notify_me=True,
                              peak_likes=(57, 585),
                               peak_comments=(21, 182),
                                peak_follows=(48, None),
                                 peak_unfollows=(35, 402),
                                  peak_server_calls=(None, 4700))

Parameters:

enabled: put True to activate or False to deactivate supervising any time

peak_likes: the first value indicates the hourly and the second indicates the daily peak value

  • e.g. in peak_likes=(66, 700) - 66 is the hourly, and 700 is the daily peak value
    such as,
    • peak_server_calls=(500, 4745) will supervise server calls with hourly peak of 500 and daily peak of 4745
    • peak_likes=(70, None) will supervise only hourly likes with the peak of 70
    • peak_unfollows=(None, 350) will supervise only daily unfollows with the peak of 350
    • peak_comments=(None, None) will not supervise comments at all

If you don't want to supervise likes at all, simply remove peak_likes parameter OR use peak_likes=(None, None).
Once likes reach peak, it will jump every other like, yet, will do all available actions (e.g. follow or unfollow).

  • Only server calls does not jump, it exits the program once reaches the peak.

Although, you can put server calls to sleep once reaches peak, read sleep_after parameter.

  • Every action will be jumped separately after reaching it's peak, except comments. Cos commenting without a like isn't welcomed that's why as like peak is reached, it will jump comments, too.

Notice: peak_likes=(50) will not work, use peak_likes=(50, None) to supervise hourly peak and peak_likes=(None, 50) for daily peak.

Same form applies to all actions. Just specify the peaks in desired intervals- hourly or daily you want to supervise.

sleep_after: is used to put InstaPy to sleep after reaching peak rather than jumping the action (or exiting- for server calls)
Any action can be included ["likes", "comments", "follows", "unfollows", "server_calls"].
As if you want to put sleep only after reaching hourly like peak, put "likes_h" OR put "likes_d" for sleeping only after reaching daily like peak.
such as,

  • sleep_after=['follows_h'] will sleep after reaching hourly follow peak
  • sleep_after=['likes_d', 'follows', 'server_calls_h'] will sleep after reaching daily like peak, follow peaks (hourly and daily) and hourly server call peak.

Notice: there can be either "likes" (for both hourly and daily sleep) OR "likes_h" (for hourly sleep only) OR "likes_d" (for daily sleep only).

Once gone to sleep, it will wake up as new hour/day (according to the interval) arrives AND continue the activity.

sleepyhead: can help to sound more humanly which will wake up a little bit later in a randomly chosen time interval around accurate wake up time.

e.g., if remaining time is 17 minutes, it will sleep 20 minutes instead (random values each time)..

stochastic_flow: can provide smooth peak value generation by your original values.

  • Every ~hour/day it will generate peaks at close range around your original peaks (but below them).

e.g., your peak likes hourly is 45, next hour that peak will be 39, the next 43, etc.

notify_me: sends toast notifications (directly to your OS) about the important states of supervisor- sleep, wake up and exit messages.

Mini-Examples:

  • Claudio has written a new 😊 quickstart script where it mostly put likes and comments. He wants the program to comment safely cos he is afraid of exceeding hourly & daily comment limits,
session.set_quota_supervisor(enabled=True, peak_comments=(21, 240))

That's it! When it reaches the comments peak, it will just jump all of the comments and will again continue to put comments when is available [in the next hour/day].

  • Alicia has a 24/7 🕦 working quickstart script and would like to keep server calls in control to AVOID excessive amount of requests to the server in hourly basis, also,
    • wants the program to sleep after reaching hourly server calls peak: adds "server_calls_h" into sleep_after parameter
    • wants the program to wake up a little bit later than real sleep time [once reaches the peaks]: uses sleepyhead=True parameter
session.set_quota_supervisor(enabled=True, peak_server_calls=(490, None) sleep_after=["server_calls_h"], sleepyhead=True)

It will sleep after hourly server calls reaches its peak given - 490 and never allow one more extra request to the server out of the peak and wake up when new hour comes in WHILST daily server calls will not be supervised at all- as Alicia wishes.

  • Sam has a casual 🦆 quickstart script full of follow/unfollow features and he wants to do it safely, also,
    • is gonna run on local computer and wants to receive toast notifications 😋 on supervising states: uses notify_me parameter
    • wants QS to randomize his pre-defined peak values [at close range] each new hour/day: uses stochastic_flow=True parameter
    • wants the program to sleep after reaching hourly follow peak and daily unfollow peak: adds "follows_h" and "unfollows_d"into sleep_after parameter
session.set_quota_supervisor(enabled=True, peak_follows=(56, 660), peak_unfollows=(49, 550) sleep_after=["follows_h", "unfollows_d"], stochastic_flow=True, notify_me=True)

Big Hint: Find your NEED 🤔 and supervise it!

  • EITHER fully configure QS to supervise all of the actions all time
  • OR just supervise the desired action(s) in desired interval(s) [hourly and/or daily] per your need

Relationship tools

Grab Followers of a user

Gets and returns followers of the given user in desired amount, also can save locally
popeye_followers = session.grab_followers(username="Popeye", amount="full", live_match=True, store_locally=True)
##now, `popeye_followers` variable which is a list- holds the `Followers` data of "Popeye" at requested time

Parameters:

username:
A desired username to grab its followers

  • It can be your own username OR a username of some non-private account.

amount:
Defines the desired amount of usernames to grab from the given account

  • amount="full":
    • Grabs followers entirely
  • amount=3089:
    • Grabs 3089 usernames if exist, if not, grabs available amount

live_match:
Defines the method of grabbing Followers data

Knowledge Base:
Every time you grab Followers data in "full" range of any user, it is also gonna be stored in some corner of InstaPy for that session.

  • live_match=False:
    • If the user already do have a Followers data loaded earlier in the same session, it will run a smart data-matching algorithm.
      And there, it will load only the new data from the server and then return a compact result of current data.
      The algorithm works like: load the usernames until hits the ones from the previous query at certain amount.
    • Also if the live_match is False and the user has no any sessional Followers data, then it will load live data at requested range.
    • As a result, live_match=False saves lots of precious time and server requests.
  • live_match=True:
    • It will always load live data from the server at requested range.

store_locally:
Gives the option to save the loaded Followers data in a local storage
The files will be saved into your logs folder, ~/InstaPy/logs/YourOwnUsername/relationship_data/Popeye/followers/ directory.
Sample filename 14-06-2018~full~6874.json:

  • 14-06-2018 means the time of the data acquisition.
  • "full" means the range of the data acquisition;
    If the data is requested at the range else than "full", it will write that range.
  • 6874 means the count of the usernames retrieved.
  • json is the filetype and the data is stored as a list in it.

There are several use cases of this tool for various purposes.
E.g., inside your quickstart script, you can do something like this:

#get followers of "Popeye" and "Cinderella"
popeye_followers = session.grab_followers(username="Popeye", amount="full", live_match=True, store_locally=True)
sleep(600)
cinderella_followers = session.grab_followers(username="Cinderella", amount="full", live_match=True, store_locally=True)

#find the users following "Popeye" WHO also follow "Cinderella" :D
popeye_cinderella_followers = [follower for follower in popeye_followers if follower in cinderella_followers]

PROs:

You can use this tool to take a backup of your or any other user's current followers.

Grab Following of a user

Gets and returns following of the given user in desired amount, also can save locally
lazySmurf_following = session.grab_following(username="lazy.smurf", amount="full", live_match=True, store_locally=True)
##now, `lazySmurf_following` variable which is a list- holds the `Following` data of "lazy.smurf" at requested time

Parameters:

username:
A desired username to grab its following

  • It can be your own username OR a username of some non-private account.

amount:
Defines the desired amount of usernames to grab from the given account

  • amount="full":
    • Grabs following entirely
  • amount=3089:
    • Grabs 3089 usernames if exist, if not, grabs available amount

live_match:
Defines the method of grabbing Following data

Knowledge Base:
Every time you grab Following data in "full" range of any user, it is also gonna be stored in some corner of InstaPy for that session.

  • live_match=False:
    • If the user already do have a Following data loaded earlier in the same session, it will run a smart data-matching algorithm.
      And there, it will load only the new data from the server and then return a compact result of current data. The algorithm works like: load the usernames until hits the ones from the previous query at certain amount.
    • Also if the live_match is False and the user has no any sessional Following data, then it will load live data at requested range.
    • As a result, live_match=False saves lots of precious time and server requests.
  • live_match=True:
    • It will always load live data from the server at requested range.

store_locally:
Gives the option to save the loaded Following data in a local storage
The files will be saved into your logs folder, ~/InstaPy/logs/YourOwnUsername/relationship_data/lazy.smurf/following/ directory.
Sample filename 15-06-2018~full~2409.json:

  • 15-06-2018 means the time of the data acquisition.
  • "full" means the range of the data acquisition;
    If the data is requested at the range else than "full", it will write that range.
  • 2409 means the count of the usernames retrieved.
  • json is the filetype and the data is stored as a list in it.

There are several use cases of this tool for various purposes.
E.g., inside your quickstart script, you can do something like this:

##as we know that all lazy Smurf care is to take some good rest, so by mistake, he can follow somebody WHOM Gargamel also follow!
#so let's find it out to save Smurfs from troubles! :D

#get following of "lazy.smurf" and "Gargamel"
lazySmurf_following = session.grab_following(username="lazy.smurf", amount="full", live_match=True, store_locally=True)
sleep(600)
gargamel_following = session.grab_following(username="Gargamel", amount="full", live_match=True, store_locally=True)

#find the users "lazy.smurf" is following WHOM "Gargamel" also follow :D
lazySmurf_gargamel_following = [following for following in lazySmurf_following if following in gargamel_following]

PROs:

You can use this tool to take a backup of your or any other user's current following.

Pick Unfollowers of a user

Compares the followers stored in a local storage against current followers and returns absent followers
all_unfollowers, active_unfollowers = session.pick_unfollowers(username="Bernard_bear", compare_by="month", compare_track="first", live_match=True, store_locally=True, print_out=True)
##now, `all_unfollowers` and `all_unfollowers` variables which are lists- hold the `Unfollowers` data of "Bernard_bear" at requested time
#`all_unfollowers` holds all of the unfollowers WHILST `active_unfollowers` holds the unfollowers WHOM "Bernard_bear" is still following

Parameters:

username:
A desired username to pick its unfollowers

  • It can be your own username OR a username of some non-private account.

compare_by: Defines the compare point to pick unfollowers

  • Available values are:

    • "latest" chooses the very latest record from the existing records in the local folder
    • "earliest" chooses the very earliest record from the existing records in the local folder

    The compare points below needs a compare track defined, too:

    • "day" chooses from the existing records of today in the local folder
    • "month" chooses from the existing records of this month in the local folder
    • "year" chooses from the existing records of this year in the local folder

compare_track: Defines the track to choose a file to compare for "day", "month" and "year" compare points

  • Available values are:
    • "first" selects the first record from the given day, month or year
    • "median" selects the median (the one in the middle) record from the given day, month or year
    • "last" selects the last record from the given day, month or year

live_match:
Defines the method of grabbing new Followers data to compare with existing data

Knowledge Base:
Every time you grab Followers data in "full" range of any user, it is also gonna be stored in some corner of InstaPy for that session.

  • live_match=False:
    • If the user already do have a Followers data loaded earlier in the same session, it will run a smart data-matching algorithm.
      And there, it will load only the new data from the server and then return a compact result of current data.
      The algorithm works like: load the usernames until hits the ones from the previous query at certain amount.
    • Also if the live_match is False and the user has no any sessional Followers data, then it will load live data at requested range.
    • As a result, live_match=False saves lots of precious time and server requests.
  • live_match=True:
    • It will always load live data from the server at requested range.

store_locally:
Gives the option to save the loaded Unfollowers data in a local storage
There will be 2 files saved in their own directory:

  • all_unfollowers:
    • Will store all of the unfollowers in there
    • Its files will be saved at logs folder, ~/InstaPy/logs/YourOwnUsername/relationship_data/Bernard_bear/unfollowers/all_unfollowers/ directory.
  • active_unfollowers:
    • Will store only the unfollowers WHOM you are currently following.
    • Its files will be saved at logs folder, ~/InstaPy/logs/YourOwnUsername/relationship_data/Bernard_bear/unfollowers/active_unfollowers/ directory.

Sample filename 03-06-2018~all~75.json:

  • 03-06-2018 means the time of the data acquisition.
  • "all" means that it is all of the unfollowers data;
    *"active" unfollowers files will have "active" written in there.
  • 75 means the count of the unfollowers retrieved.
  • json is the filetype and the data is stored as a list in it.

print_out:
Use this parameter if you would like the see those unfollowers printed into the console output right after finding them.

There are several use cases of this tool for various purposes.

  • You can the get the unfollowers you have had from the start of the year, or from the middle of the year or from the start of the month, etc.
    And then, e.g. do some useful analysis with that generated unfollowers data.
  • And you can also find the unfollowers to block them all.
  • Also, you can unfollow back those active unfollowers right away:
#find all of the active unfollowers of Bernard bear
all_unfollowers, active_unfollowers = session.pick_unfollowers(username="Bernard_bear", compare_by="earliest", compare_track="first", live_match=True, store_locally=True, print_out=True)
sleep(200)
#let's unfollow them immediately cos Bernard will be angry if heards about those unfollowers! :D
session.unfollow_users(amount=len(active_unfollowers), customList=(True, active_unfollowers, "all"), style="RANDOM", unfollow_after=None, sleep_delay=600)

Pick Nonfollowers of a user

Compares the Followers data against Following data of a user and returns the Nonfollowers data
scoobyDoo_nonfollowers = session.pick_nonfollowers(username="ScoobyDoo", live_match=True, store_locally=True)
#now, `scoobyDoo_nonfollowers` variable which is a list- holds the `Nonfollowers` data of "ScoobyDoo" at requested time

Parameters:

username:
A desired username to pick its nonfollowers

  • It can be your own username OR a username of some non-private account.

live_match:
Defines the method of grabbing Followers and Following data to compare with each other to find nonfollowers

Knowledge Base:
Every time you grab Followers and/or Following data in "full" range of any user, it is also gonna be stored in some corner of InstaPy for that session.

  • live_match=False:
    • If the user already do have a Followers and/or Following data loaded earlier in the same session, it will run a smart data-matching algorithm.
      And there, it will load only the new data from the server and then return a compact result of current data.
      The algorithm works like: load the usernames until hits the ones from the previous query at certain amount.
    • Also if the live_match is False and the user has no any sessional Followers and/or Following data, then it will load live data at requested range.
    • As a result, live_match=False saves lots of precious time and server requests.
  • live_match=True:
    • It will always load live data from the server at requested range.

store_locally:
Gives the option to save the loaded Nonfollowers data in a local storage
The files will be saved into your logs folder, ~/InstaPy/logs/YourOwnUsername/relationship_data/ScoobyDoo/nonfollowers/ directory.
Sample filename 01-06-2018~[5886-3575]~2465.json:

  • 01-06-2018 means the time of the data acquisition.
  • 5886 means the count of the followers retrieved.
  • 3575 means the count of the following retrieved.
  • 2465 means the count of the nonfollowers picked.
  • json is the filetype and the data is stored as a list in it.

There are several use cases of this tool for various purposes.

  • You can get the nonfollowers of several users and then do analysis.
    • e.g., in this example Scooby Do used it like this:
    ##Scooby Doo always wonders a lot and this time he wonders if there are people Shaggy is following WHO do not follow him back...
    shaggy_nonfollowers = session.pick_nonfollowers(username="Shaggy", live_match=True, store_locally=True)
    
    #now Scooby Doo will tell his friend Shaggy about this, who knows, maybe Shaggy will unfollow them all or even add to block :D

Pick Fans of a user

Returns Fans data- all of the accounts who do follow the user WHOM user itself do not follow back
smurfette_fans = session.pick_fans(username="Smurfette", live_match=True, store_locally=True)
#now, `smurfette_fans` variable which is a list- holds the `Fans` data of "Smurfette" at requested time

Parameters:

username:
A desired username to pick its fans

  • It can be your own username OR a username of some non-private account.

live_match:
Defines the method of grabbing Followers and Following data to compare with each other to find fans

Knowledge Base:
Every time you grab Followers and/or Following data in "full" range of any user, it is also gonna be stored in some corner of InstaPy for that session.

  • live_match=False:
    • If the user already do have a Followers and/or Following data loaded earlier in the same session, it will run a smart data-matching algorithm.
      And there, it will load only the new data from the server and then return a compact result of current data.
      The algorithm works like: load the usernames until hits the ones from the previous query at certain amount.
    • Also if the live_match is False and the user has no any sessional Followers and/or Following data, then it will load live data at requested range.
    • As a result, live_match=False saves lots of precious time and server requests.
  • live_match=True:
    • It will always load live data from the server at requested range.

store_locally:
Gives the option to save the loaded Fans data in a local storage
The files will be saved into your logs folder, ~/InstaPy/logs/YourOwnUsername/relationship_data/Smurfette/fans/ directory.
Sample filename 05-06-2018~[4591-2575]~3477.json:

  • 05-06-2018 means the time of the data acquisition.
  • 4591 means the count of the followers retrieved.
  • 2575 means the count of the following retrieved.
  • 3477 means the count of the fans picked.
  • json is the filetype and the data is stored as a list in it.

There are several use cases of this tool for various purposes.

  • You can get the fans of several users and then do analysis.
    • e.g., in this example Smurfette used it like this:
    ##Smurfette is so famous in the place and she wonders which smurfs is following her WHOM she doesn't even know of :D
    smurfette_fans = session.pick_fans(username="Smurfette", live_match=True, store_locally=True)
    #and now, maybe she will follow back some of the smurfs whom she may know :P

Pick Mutual Following of a user

Returns Mutual Following data- all of the accounts who do follow the user WHOM user itself also do follow back
Winnie_mutualFollowing = session.pick_mutual_following(username="WinnieThePooh", live_match=True, store_locally=True)
#now, `Winnie_mutualFollowing` variable which is a list- holds the `Mutual Following` data of "WinnieThePooh" at requested time

Parameters:

username:
A desired username to pick its mutual following

  • It can be your own username OR a username of some non-private account.

live_match:
Defines the method of grabbing Followers and Following data to compare with each other to find mutual following

Knowledge Base:
Every time you grab Followers and/or Following data in "full" range of any user, it is also gonna be stored in some corner of InstaPy for that session.

  • live_match=False:
    • If the user already do have a Followers and/or Following data loaded earlier in the same session, it will run a smart data-matching algorithm.
      And there, it will load only the new data from the server and then return a compact result of current data.
      The algorithm works like: load the usernames until hits the ones from the previous query at certain amount.
    • Also if the live_match is False and the user has no any sessional Followers and/or Following data, then it will load live data at requested range.
    • As a result, live_match=False saves lots of precious time and server requests.
  • live_match=True:
    • It will always load live data from the server at requested range.

store_locally:
Gives the option to save the loaded Mutual Following data in a local storage
The files will be saved into your logs folder, ~/InstaPy/logs/YourOwnUsername/relationship_data/WinnieThePooh/mutual_following/ directory.
Sample filename 11-06-2018~[3872-2571]~1120.json:

  • 11-06-2018 means the time of the data acquisition.
  • 3872 means the count of the followers retrieved.
  • 2571 means the count of the following retrieved.
  • 1120 means the count of the mutual following picked.
  • json is the filetype and the data is stored as a list in it.

There are several use cases of this tool for various purposes.

  • You can get the mutual following of several users and then do analysis.
    • e.g., in this example Winnie The Pooh used it like this:
    #Winnie The Pooh is a very friendly guy and almost everybody follows him back, but he wants to be sure about it :D
    Winnie_mutual_following = session.pick_mutual_following(username="WinnieThePooh", live_match=True, store_locally=True)
    ##now, he will write a message to his mutual followers to help him get a new honey pot :>

Use a proxy

You can use InstaPy behind a proxy by specifying server address and port

session = InstaPy(username=insta_username, password=insta_password, proxy_address='8.8.8.8', proxy_port=8080)

To use proxy with authentication you should firstly generate proxy chrome extension (works only with Chrome and headless_browser=False).

from proxy_extension import create_proxy_extension

proxy = 'login:password@ip:port'
proxy_chrome_extension = create_proxy_extension(proxy)

session = InstaPy(username=insta_username, password=insta_password, proxy_chrome_extension=proxy_chrome_extension, nogui=True)

Switching to Firefox

Chrome is the default browser, but InstaPy provides support for Firefox as well.

session = InstaPy(username=insta_username, password=insta_password, use_firefox=True)

Emoji Support

To use an emoji just add an u in front of the opening apostrophe:

session.set_comments([u'This post is 🔥',u'More emojis are always better 💯',u'I love your posts 😍😍😍']);
# or
session.set_comments([u'Emoji text codes are also supported :100: :thumbsup: :thumbs_up: \u2764 💯💯']);

Emoji text codes are implemented using 2 different naming codes. A complete list of emojis codes can be found on the Python Emoji Github, but you can use the alternate shorted naming scheme found for Emoji text codes here. Note: Every Emoji has not been tested. Please report any inconsistencies.

Legacy Emoji Support

You can still use Unicode strings in your comments, but there are some limitations.

  1. You can use only Unicode characters with no more than 4 characters and you have to use the unicode code (e. g. \u1234). You find a list of emoji with unicode codes on Wikipedia, but there is also a list of working emoji in /assets

  2. You have to convert your comment to Unicode. This can safely be done by adding an u in front of the opening apostrophe: u'\u1234 some comment'

Clarifai ImageAPI

Note: Head over to https://developer.clarifai.com/signup/ and create a free account, once you’re logged in go to https://developer.clarifai.com/account/applications/ and create a new application. You can find the client ID and Secret there. You get 5000 API-calls free/month.

If you want the script to get your CLARIFAI_API_KEY for your environment, you can do:

export CLARIFAI_API_KEY="<API KEY>"

Example with Imagecontent handling

session.set_do_comment(True, percentage=10)
session.set_comments(['Cool!', 'Awesome!', 'Nice!'])
session.set_use_clarifai(enabled=True)
session.clarifai_check_img_for(['nsfw'])
session.clarifai_check_img_for(['food', 'lunch', 'dinner'], comment=True, comments=['Tasty!', 'Nice!', 'Yum!'])

session.end()

Enabling Imagechecking

# default enabled=False , enables the checking with the Clarifai API (image
# tagging) if secret and proj_id are not set, it will get the environment
# variables 'CLARIFAI_API_KEY'.

session.set_use_clarifai(enabled=True, api_key='xxx')

Filtering inappropriate images

# uses the clarifai api to check if the image contains nsfw content
# -> won't comment if image is nsfw

session.clarifai_check_img_for(['nsfw'])

Filtering by keyword

# uses the clarifai api to check if the image concepts contain the keyword(s)
# -> won't comment if image contains the keyword

session.clarifai_check_img_for(['building'])

Specialized comments for images with specific content

# checks the image for keywords food and lunch. To check for both, set full_match in 
# in session.set_use_clarifia to True, and if both keywords are found,
# InstaPy will comment with the given comments. If full_match is False (default), it only
# requires a single tag to match Clarifai results.

session.set_use_clarifai(enabled=True, api_key='xxx', full_match=True)
session.clarifai_check_img_for(['food', 'lunch'], comment=True, comments=['Tasty!', 'Yum!'])


# To adjust the threshold for accepted concept predictions
# and their respective score (degree of confidence)
# you can set the default probability parameter for Clarifai (default 50%).
# For example, if you only want to accept results with a high degree of confidence,
# you could set probability to 90%.

session.set_use_clarifai(enabled=True, api_key='xxx', probability=0.90, full_match=True)
session.clarifai_check_img_for(['food', 'lunch'], comment=True, comments=['Tasty!', 'Yum!'])
Check out https://clarifai.com/demo to see some of the available tags.

Running on a Server

Use the nogui parameter to interact with virtual display

session = InstaPy(username='test', password='test', nogui=True)

Running on a Headless Browser

Note: Chrome only! Must use chromedriver v2.9+

Use headless_browser parameter to run the bot via the CLI. Works great if running the scripts locally, or to deploy on a server. No GUI, less CPU intensive. Example

session = InstaPy(username='test', password='test', headless_browser=True)

Running Multiple Accounts

Use the multi_logs parameter if you are going to use multiple accounts and want the log files stored per account.

session = InstaPy(username='test', password='test', multi_logs=True)

Running with Docker microservices manual

Docker allows very easy and fast run of the instapy bot without any pain and tears.

0. Preparations

Install docker from the official website https://www.docker.com/

Install VNC viewer if you do not have one. For windows, a good program is http://www.tightvnc.com/

1. Set your instagram login and password

Open docker_quickstart.py and fill the quotes after insta_username and insta_password with your credentials.

Don't forget to make other changes for the file as you want to. Read the documentation above for info.

2. Run and build containers with docker-compose

First you need to open your terminal, move to the root folder (usually with the cd command) of instapy project and then type:

docker-compose up -d --build

That's all! At this step, you are already successfully running your personal bot!

3. See what your bot can do right now

Run your VNC viewer, and type address and port localhost:5900. The password is secret.

4. Stop your instapy bot

Use your terminal again, type in the same window:

docker-compose down

Your bot is stopped!

5. Further steps

Those are just basic steps to run instapy bot on your PC with docker. There are other docker-compose settings file in the root of project.

Development environment to run, test and debug by SSH

Use it to help us with development and test instapy! docker-dev.yml file.

docker-compose -f docker-dev.yml up -d

After striking this command, you can access your bot by VNC on the adress localhost:5901, the password is secret.

But there is more! There is a fully accessible bash console with all code mounted at the path /code. When you hack some files they are dynamically updated inside your container.

To access yor container console to run bot type localhost:22 in your favorite ssh client. The User is root and the password is root also.

Run in production without opened VNC port

Suitable to run in a remote server. Attention! You can not view what happened through VNC on this configuration docker-prod.yml file.

docker-compose -f docker-prod.yml up -d

Running all-in-one with Docker (obsolete)

1. Build the Image

First you need to build the image by running this in the Terminal:

docker build -t instapy ./docker_conf/all_in_one

Make sure to use the nogui feature:

# you can use the nogui parameter to use a virtual display

session = InstaPy(username='test', password='test', nogui=True)

2. Run in a Container

After the build succeeds, you can simply run the container with:

docker run --name=instapy -e INSTA_USER=<your-user> -e INSTA_PW=<your-pw> -d --rm instapy

Automate InstaPy

Windows Task Scheduler

You can use Window's built in Task Scheduler to automate InstaPy, using a variety of trigger types: time, login, computer idles, etc. To schedule a simple daily run of an Instapy script follow the below directions

  1. Open Windows Task Scheduler
  2. Select "Create Basic Task"
  3. Fill out "Name" and "Description" as desired, click "Next"
  4. On "Trigger" screen select how frequently to run, click "Next" (Frequency can be modified later)
  5. On "Daily" screen, hit "Next"
  6. "Action Screen" select "Start a program" and then click "Next"
  7. "Program/script" enter the path, or browse to select the path to python. (How to find python path on Windows)
  8. "Add arguments" input the InstaPy script path you wish to run. (Example: C:\Users\USER_NAME\Documents\GitHub\InstaPy\craigquick.py)
  9. "Start in" input Instapy install location (Example: C:\Users\USER_NAME\Documents\GitHub\InstaPy). Click "Next"
  10. To finish the process, hit "Finish"

cron

You can add InstaPy to your crontab, so that the script will be executed regularly. This is especially useful for servers, but be sure not to break Instagrams follow and like limits.

# Edit or create a crontab
crontab -e
# Add information to execute your InstaPy regularly.
# With cd you navigate to your InstaPy folder, with the part after &&
# you execute your quickstart.py with python. Make sure that those paths match
# your environment.
45 */4 * * * cd /home/user/InstaPy && /usr/bin/python ./quickstart.py

Schedule

Schedule is an in-process scheduler for periodic jobs that uses the builder pattern for configuration. Schedule lets you run Python functions periodically at pre-determined intervals using a simple, human-friendly syntax.

pip install schedule
from instapy import InstaPy
import schedule
import time

def job():
    try:
        session = InstaPy(selenium_local_session=False) # Assuming running in Compose
        session.set_selenium_remote_session(selenium_url='http://selenium:4444/wd/hub')
        session.login()
        session.set_do_comment(enabled=True, percentage=20)
        session.set_comments(['Well done!'])
        session.set_do_follow(enabled=True, percentage=5, times=2)
        session.like_by_tags(['love'], amount=100, media='Photo')
        session.end()
    except:
        import traceback
        print(traceback.format_exc())

schedule.every().day.at("6:35").do(job)
schedule.every().day.at("16:22").do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

Extra Information

Using one of the templates

If you're interested in what other users setup looks like, feel free to check out the quickstart_templates folder which includes several working setups with different features.

In order to use them, just copy the desired file and put it next to the quickstart.py file in the, what is called root, directory.

Finally simply adjust the username and any tags or firend lists before executing it. That's it.

How not to be banned

  • Built-in delays prevent your account from getting banned. (Just make sure you don't like 1000s of post/day)
  • Use the Quota Supervisor feature to set some fixed limits for the bot for maximum safety.

Chrome Browser

64-bit system is a requirement for current versions of chrome browser.

Simulation

During indirect data retrieval, simulation happens to provide a genuine activity flow triggered by a wise algorithm.

To turn off simulation or to decrease its occurrence frequency, use set_simulation setting:

#use the value of `False` to permanently turn it off
session.set_simulation(enabled=False)

#use a desired occurrence percentage
session.set_simulation(enabled=True, percentage=66)

Disable Image Loading

If you want to save some bandwidth, you can simply disable the image/video loading. This will lead to, if you watch InstaPy running, not downloading and displaying any more images and videos.

Note: This can save a tremendous amount of data. This is turned off by default (False).

To do this simply pass the disable_image_load=True parameter in the InstaPy constructor like so:

session = InstaPy(username=insta_username,
                  password=insta_password,
                  headless_browser=False,
		  disable_image_load=True,
                  multi_logs=True)

Using Multiple Chromedrivers

If you need multiple os versions of chromedriver just rename it like:

chromedriver_linux
chromedriver_osx
chromedriver_windows

Changing DB or Chromedriver locations

If you want to change the location/path of either the DB or the chromedriver, simply head into the instapy/settings.py file and change the following lines. Set these in instapy/settings.py if you're locating the library in the /usr/lib/pythonX.X/ directory.

Settings.database_location = '/path/to/instapy.db'
Settings.chromedriver_location = '/path/to/chromedriver'

Have Fun & Feel Free to report any issues