Skip to content

Commit

Permalink
Patches, code and config's structure reformatted and added new features
Browse files Browse the repository at this point in the history
Code structure reformatted
Config.ini structure reformatted
Added force_search and specific_file as parameters to config
Patch - Clicking on a random user while scrolling down
Patch - Scrolling up a bit while scrolling down
Added 'ctrl+c' (SIGINT) to stop execution and save all work done until the moment
New informative messages in CLI
Waiting time more efficient and cleaner
README.md edited

Solved patch by executing JavaScript to scroll down
  • Loading branch information
Fytex committed Sep 30, 2020
1 parent f627fa5 commit 151c164
Show file tree
Hide file tree
Showing 8 changed files with 559 additions and 290 deletions.
57 changes: 31 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
## How does this bot work?
It works as a browser simulator using selenium.

There are four steps:
At the beginning there are four steps (It will save data in order to don't waste your time):

1. Log in
2. Find user from post
2. Find post's owner
3. Find followers/followings
4. Start spamming mentions in the post

Expand All @@ -34,13 +34,13 @@ But don't worry... if you feel unsafe you can install these files by yourself (j

### Setup

1. Install Google Chrome (Check `config.ini` Chrome's category if you want a different path) -> if you guys start complaining about this specific step I'll make some updates to have wider options
1. Install Google Chrome (Check Browser's category in `config.ini` if you want a different path) -> if you guys start complaining about this specific step I'll make some updates to have wider options
2. Install Python 3.6+ (Don't forget to add in system variable `PATH`)
3. Open terminal, change directory to Instagram-Giveaways-Winner's folder and type: `pip install -r requirements.txt`
4. Edit config.ini (See next category)
4. Edit `config.ini` (See next category)
5. In the same terminal type: `py script.py`

Warning: Avoid resizing or touching the Browser oppened. You can minimize if you want or if you want to get rid of it just change `Window` to `False` in `config.ini`
Warning: Avoid resizing or touching the Browser oppened. You can minimize if you want or if you want to get rid of it just change Window at Browser's category to `False` in `config.ini`

These commands can change depending on your configuration. Such as python/py/python3... or pip/pip3...

Expand All @@ -51,22 +51,30 @@ If you need help add me on discord or join the server and ask me (links in my pr

Browser's window can be invisible (in background) if Window's option is deactivated.

- Step 1 requires both username/email and password.
- **Login** requires both username/email and password.
- A cookie's data will be saved to login automatically in order to prevent repetitve actions.

- Step 2 will only occur if no User Target is specified in the file.
- User Target is the user where the bot will get the followers/followings to mention.
- **Find post's owner** will only occur if no User Target is specified in the file.
- User Target is the user where the bot will search for followers/followings to mention.
- The timeout is a way to prevent blocking while trying to log in by stopping the program.

- Step 3 is the search and find part where the bot saves all users.
- You can specify the limit of users in the file (it will pick the lowest one between the limit and the number of followers/followings from the User Target, the higher the number is, more time will take).
- In the file you can either choose followers or followings.
- The timeout is a way to prevent blocking while searching for followers/followings in case it gets stuck by stopping the program.

- Step 4 is where all the fun begins. It starts spamming mentions in the post.
- By enabling Save Only's option this step won't run. This option is used in case you only want to save the followers/followings and use them later.
- **Find followers/followings** is where the bot searches and saves all followers/followings.
- You can specify the limit of followers/followings (it will pick the lowest one between the limit and the number of followers/followings from the User Target).
- First it will search if there are the limit number of followers/followings inside a file in a specific file in records (database)
- If Force Search is disabled and there is no limit and a file was found then it uses that amount of followers/followings to mention.
- If Force Search is enabled or there aren't enough followers/followers in the file or file doesn't exist it will search on Instagram (User Target's followers/followings) until it meets the limit. If no limit specified then searches for all of them.
- In `config.ini` you can either choose to search for followers or followings.
- The timeout is a way to prevent blocking while searching for followers/followings in case it gets stuck.
- If you raise SIGNINT by pressing 'ctrl + c' in your keyboard. It will stop searching and will immediately save all followers/followings found into a file in records.
- If you have a custom/specific file which you want to use just set the relative path at 'Specific File' in `config.ini`.

- **Start spamming mentions in the post** is where all the fun begins. It starts spamming mentions in the post.
- By enabling SaveOnly's option this step won't run. This option is used in case you only want to save the followers/followings and use them later.
- You can edit the message and add as many mentions as you want (mentions will never be repeated).
- Interval Category in `config` file lets you choose how much time it waits before each comment. You have to find out by yourself the best interval that fits your account. It has a min, max and weight so the number isn't always the same preventing Instagram finding out it is a bot. (Later I will try to create kind of an A.I. to do this for you)
- In case you have a char that doesn't belong to BMP (such as some emojis) it will appear a different message. But your message will still be sent. (Refresh when finished or open in another browser to check everything is fine)
- Interval's category in `config.ini` file lets you choose how much time it waits before each comment. You have to find out by yourself the best interval that fits into your account. It has a min, max and weight so the number isn't always the same preventing Instagram finding out it is a bot. (The smaller the interval the higher the chance of having to wait to comment again because of Instagram's A.I.) (You have to play with these numbers until you find out the best interval range for you)
- In case you have a char that doesn't belong to BMP (such as some emojis) it will appear a different message. But your message will still be sent. (Refresh when finished or open in another browser to check everything is fine)
- By pressing 'ctrl+c' it raises SIGINT in order to stop the execution of the program.



### How do the records (database) work?
Expand All @@ -75,9 +83,8 @@ There are two sections:
- followers
- followings

Depending on what you choose it will save in the respective directory. Then it will choose the file's name using the following format `{User Target}_{total}.json` where `User Target` is the user where we got the followers/followings and `total` is the number of users we got.
When searching for a `User Target` if the lowest one between the `limit` (in the config file) and the number of followers/followings from the `User Target` is already met in a file then it will skip Step 2 and use that file automatically.

Depending on what you choose it will save in the respective directory. Then it will choose the file's name using the following format `{User Target}.txt` where `User Target` is the user where we got the followers/followings.
By following the same pattern you see on the other records (`@user` in each line) you can create a custom file (E.g. `custom.txt`) and enable Specific File in `config.ini` (removing `#`) and changing the value to the path (E.g. `records\custom.txt`)


### How do the cookies work (auto-login)?
Expand All @@ -89,14 +96,12 @@ When the program logs into your account it saves in a separated folder called `c

I would recommend using an alternative account which you aren't afraid of losing because it could go wrong in the worst case. However I've never experienced any bad situations using this script.

Instagram has a comment's request rate-limit to avoid spamming. From my research it has an algorithm which varies from user to user. Since Instagram doesn't provide a time for reset we have to try every x seconds. We chose it to be every 10 seconds. If a message pops up saying that it couldn't post the comment its because you hit that rate-limit so you just have to wait. (You don't have to do anything its all automatic)

Instagram has a comment's request rate-limit to avoid spamming. From my research it has an algorithm which varies from user to user. Since Instagram doesn't provide a time for reset we have to try every x seconds. In `config.ini` at Interval's category you can choose the range of the intervale by setting the minimum, maximum and the most probable number for the interval between comments (Better a range of numbers instead of always the same number in order to avoid being rate-limited). If a message pops up saying that it couldn't post the comment its because you hit that rate-limit so you just have to wait. (You don't have to do anything its all automatic but if this happens you should consider raising those intervals)
If you want to be able to send more comments you have to make a good use of your account (following, commenting, liking, etc.). That's how Instagram's A.I.'s works.

#### Future Updates:
- [ ] Add a followers/followings tracker so it won't repeat the count if we restart the bot
- [ ] Add a way to find followers/followings some at a time until it reaches the limit/maximum. This way we can find followers/followings and post comments in a cycle.
- [ ] Set a specific file from records (database) to use as users to mention
- [ ] Find out the best interval between each comment for your account
- [ ] Find out the best interval between each comment for your account (This requires researching and planning by using a lot of my time. Don't see when this would release because I'm not being financially paid for this)
- [ ] Compatibility with more browsers


Expand All @@ -105,4 +110,4 @@ Instagram has a comment's request rate-limit to avoid spamming. From my research
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: cannot find Chrome binary
```
- Since Chrome has updated their files' location, Selenium hasn't fixed it yet. Check `config.ini` Chrome's Category to fix it.
- Since Chrome has updated their files' location, Selenium hasn't fixed it yet. Check `config.ini` Browser's Category to fix it.
49 changes: 29 additions & 20 deletions config.ini
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
[Required]

Post Link = url
Post Link = https://www.instagram.com/p/code/
# Post Link can be disabled (writing # before Post Link) only in case if Save Only is enabled and a User Target specified

Expression = I want to win this giveaway! @, @
Expression = \@StaticUser, I'm here to mention two of my friends. @ and @
# Use @ to choose where to write each mention
# in case you want to write a specific @ use the
# following escape character '\' like this \@fytex
# You can edit this message as much as you want
# and add as many mentions as you want
# In case you want to write a specific @ use the following escape character '\' like this \@fytex
# You can edit this message as much as you want and add as many mentions as you want even special characters and emojis
# If no mentions then it doesn't search for followers/followings except if Save Only is enabled

Username = username

Expand All @@ -17,23 +16,26 @@

[Optional] # Remove '#' before each line to enable option

#Window = True
# Show Web Browser (if not then runs in background)

#User Target = User
# User to pick followers/followings for mentions
#User Target = usertarget
# User to search for followers/followings

#Followers = True
# if True then uses UserTarget's followers
# if False then uses UserTarget's followings
#Followers = False
# if True then searches for User Target's followers
# if False then searches for User Target's followings

#Limit = 200
#Limit = 200
# Limit of users to mention (This corresponds to the maximum number of users to fetch during followers/followings' search)
# Warning: Enable this and set a limit if User Target has too many followers/followings otherwise you will have to wait a long time or stop the operation
# You can stop the operation of searching by pressing 'ctrl + c' [SIGINT] and all the followers/followings searched will be saved

#Specific File = records\custom.txt
# Relative path to the records' custom file

#Timeout = 30
# Limit time to wait in case it gets stuck
#Force Search = True
# Forces searching for users to mention. This option adds new followers/followings to previous records
# You can't enable this option and have a limit at the same time

#Save Only = False
#Save Only = True
# Don't spam (only save data) [Requires either Post Link or User Target]


Expand All @@ -45,13 +47,17 @@
#Max = 120

#Weight = 90
# Weight must be a number between Min and Max
# Numbers tend to be close to Weight's number
# if not specified it will use the midpoint between Min and Max


[Chrome] # Remove '#' before each line to enable option
[Browser] # Remove '#' before each line to enable option

#Default Lang = False
#Window = False
# Show Web Browser (if not then runs in background)

#Default Lang = True
# if False it uses English
# if True it uses your Chrome's Language
# Warning: Very low chance of crashing program if True
Expand All @@ -64,3 +70,6 @@
#
# enable this option because Chrome is changing paths and Selenium hasn't fixed yet.
# if error still persists find where Chrome is located and put the path ending in the executable

#Timeout = 30
# Limit time to wait in case it gets stuck (don't change this except if your internet/computer is too slow and so raise the number)
2 changes: 2 additions & 0 deletions modules/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .browser import Tab
from .instagram_bot import Bot
74 changes: 74 additions & 0 deletions modules/browser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import os

from selenium import webdriver # type: ignore
from typing import Optional
from sys import platform

class Browser:
def __init__(self, window:bool=True, binary_location:Optional[str]=None, default_lang:bool=False, **kwargs):

if platform == 'linux' or platform == 'linux2':
driver_file_name = 'chrome_linux'
elif platform == 'win32':
driver_file_name = 'chrome_windows.exe'
elif platform == 'darwin':
driver_file_name = 'chrome_mac'

driver_path = os.path.join(os.getcwd() , f'drivers{os.path.sep}{driver_file_name}')

os.chmod(driver_path , 0o755)

options = webdriver.ChromeOptions()

if not default_lang:
options.add_experimental_option('prefs', {'intl.accept_languages': 'en,en_US'})

options.headless = not window ;

if binary_location:
options.binary_location = binary_location


self.driver = webdriver.Chrome(executable_path=driver_path, options=options)


class Tab:

def __init__(self, driver:webdriver.Chrome, url:str):
self.driver = driver
self.url = url


def new_tab(self, url:str='https://www.google.com'):

'''
Opens a new tab on Browser
Args:
- url : to navigate after openning tab
'''

self.driver.execute_script(f'window.open(\'{url}\');')
self.driver.switch_to.window(self.driver.window_handles[-1])


def close_tab(self):

'''
Close the last tab on Browser
'''

self.driver.close()
self.driver.switch_to.window(self.driver.window_handles[-1]) # could write 'main' but later on could be modified


def __enter__(self):
self.new_tab(self.url)


def __exit__(self, *exc):
self.close_tab()
35 changes: 35 additions & 0 deletions modules/comments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from typing import Iterator, List
from itertools import chain

class Comments:

def __init__(self, iter_connections:Iterator[str], parts_expr:List[str]):
self.iter_connections = iter_connections
self.parts_expr = parts_expr

def generate(self) -> Iterator[str]:

'''
Generates every comment from an expression and a list of connections
'''

last_part = self.parts_expr[-1]

while True:

if len(self.parts_expr) == 1:
yield last_part

else:

try:

users = next(self.iter_connections)
except StopIteration:
return

comment = ''.join(chain.from_iterable(zip(self.parts_expr, users)))

yield (comment + last_part).replace(r'\@', '@')
41 changes: 41 additions & 0 deletions modules/implicitly_wait.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from contextlib import contextmanager
from selenium import webdriver # type: ignore

class ImplicitlyWait:
def __init__(self, driver:webdriver, timeout:int):
self.driver = driver
self.timeout = timeout

def enable(self):

'''
Enable implicitly wait so it doesn't throw errors without waiting some time in order to let the element appear
'''

self.driver.implicitly_wait(self.timeout)

def disable(self):

'''
Disable implicitly wait so it doesn't wait for the element to appear. This can cause errors if not handled with a 'Explicitly Wait'
'''

self.driver.implicitly_wait(0)

@contextmanager
def ignore(self):

'''
Ingore implicitly wait in the current block of code by disabling and enabling again when finished
'''

try:
yield self.disable()
finally:
self.enable()
Loading

0 comments on commit 151c164

Please sign in to comment.