patternpythonMinor
Instagram bot script
Viewed 0 times
scriptinstagrambot
Problem
I'm very new to Python and would like some feedback on my script. I'm fairly clueless to best practices, code correctness etc. so if there's anything at all that looks wrong, isn't 'pythonic' or could be done in a simpler way, I'd love if you could point me in the right direction.
```
#!/usr/bin/env python
"""Follows Instagram users with similar taste and likes their photos.
Scrapes users who have liked a seed user's recent photos (avoiding
users whose profiles seem spammy), then likes some of their most
popular recent photos and follows them. After 3 days, unfollows them.
Required modules:
httplib2
simplejson
Version: 2.1.8
Licensed under a BSD New license.
Uses the https://github.com/Instagram/python-instagram client.
"""
import json
import logging
import os
import random
import re
import time
from instagram import client
# CUSTOMISABLE
CONFIG = {
'client_id': '',
'client_secret': '',
'redirect_uri': '',
'access_token': '',
'client_ips': ''
}
SEED_USER = 'kevin'
NUM_TO_FOLLOW = 25
NUM_TO_UNFOLLOW = 25
# END CUSTOMISABLE
# Logging stuff
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Global declarations
TILES_PATH = os.getcwd()+'/Tiles.json'
def username_to_id(username):
"""Accepts a username and returns its ID."""
user = api.user_search(q=username, count=1)
if username != user[0].username:
logger.error('Username to ID failed')
return user[0].id
def check_user(user, ids_to_avoid=[]): # TODO: Check user not super popular
"""Checks if user meets criteria to be followed, returns boolean.
Args:
user (object): An instagram.models.User object
ids_to_avoid (list): IDs to avoid, defaults to empty list
"""
if (
user.profile_picture != 'http://images.ak.instagram.com/profiles/anonymousUser.jpg'
and user.full_name
and user.bio
and re.search(r'follow|f4f|1D|one
```
#!/usr/bin/env python
"""Follows Instagram users with similar taste and likes their photos.
Scrapes users who have liked a seed user's recent photos (avoiding
users whose profiles seem spammy), then likes some of their most
popular recent photos and follows them. After 3 days, unfollows them.
Required modules:
httplib2
simplejson
Version: 2.1.8
Licensed under a BSD New license.
Uses the https://github.com/Instagram/python-instagram client.
"""
import json
import logging
import os
import random
import re
import time
from instagram import client
# CUSTOMISABLE
CONFIG = {
'client_id': '',
'client_secret': '',
'redirect_uri': '',
'access_token': '',
'client_ips': ''
}
SEED_USER = 'kevin'
NUM_TO_FOLLOW = 25
NUM_TO_UNFOLLOW = 25
# END CUSTOMISABLE
# Logging stuff
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Global declarations
TILES_PATH = os.getcwd()+'/Tiles.json'
def username_to_id(username):
"""Accepts a username and returns its ID."""
user = api.user_search(q=username, count=1)
if username != user[0].username:
logger.error('Username to ID failed')
return user[0].id
def check_user(user, ids_to_avoid=[]): # TODO: Check user not super popular
"""Checks if user meets criteria to be followed, returns boolean.
Args:
user (object): An instagram.models.User object
ids_to_avoid (list): IDs to avoid, defaults to empty list
"""
if (
user.profile_picture != 'http://images.ak.instagram.com/profiles/anonymousUser.jpg'
and user.full_name
and user.bio
and re.search(r'follow|f4f|1D|one
Solution
You have an error in
If the first check passes but the second doesn't, this will implicitly
You have a lot of code there without too much structure. First off, it's general practice to have a defined entry point function (usually
This means "if the script is being run directly (i.e. not imported), call
It is not clear why
You could also split out some of the other functionality into separate functions, e.g.
Good work on following the style guide. One minor thing (emphasis mine):
Imports should be grouped in the following order:
You should put a blank line between each group of imports.
Finally, you could consider giving this a CLI to provide the various config values. Look into e.g.
check_user:def check_user(...):
if (...):
rel = api.user_relationship(...)
if (...):
return True
else:
return FalseIf the first check passes but the second doesn't, this will implicitly
return None. The minimal fix is:def check_user(...):
if (...):
rel = api.user_relationship(...)
if (...):
return True
return FalseYou have a lot of code there without too much structure. First off, it's general practice to have a defined entry point function (usually
main) that is called as follows, at the end of the script:if __name__ == '__main__':
main()This means "if the script is being run directly (i.e. not imported), call
main". It is not clear why
scrape_users is defined inline like that. I would move it up with the other function definitions, and make e.g. api a parameter. In general, you could use more explicit parameters and return values, rather than relying on scoping. You could also split out some of the other functionality into separate functions, e.g.
unfollow and follow_and_like. This would make your main very simple and avoid the current situation where you can't see the try and except KeyboardInterrupt without a lot of scrolling. Good work on following the style guide. One minor thing (emphasis mine):
Imports should be grouped in the following order:
- standard library imports
- related third party imports
- local application/library specific imports
You should put a blank line between each group of imports.
Finally, you could consider giving this a CLI to provide the various config values. Look into e.g.
argparse for dealing with arguments.Code Snippets
def check_user(...):
if (...):
rel = api.user_relationship(...)
if (...):
return True
else:
return Falsedef check_user(...):
if (...):
rel = api.user_relationship(...)
if (...):
return True
return Falseif __name__ == '__main__':
main()Context
StackExchange Code Review Q#58804, answer score: 4
Revisions (0)
No revisions yet.