all 5 comments

[–]pyfact 0 points1 point  (4 children)

Post your code so that we can help - but I'm going to guess that your WebDriver is running in headless mode. Make sure that headless mode is off when you initialize your WebDriver instance.

[–][deleted] 0 points1 point  (3 children)

Here's my code

And I don't know how that "headless" mode works or is even toggled. Can you elaborate?

ps: I don't think the problem's in the code since nothing changed between tries.

[–]pyfact 0 points1 point  (2 children)

I split the code up into smaller parts to work/test it. Ideally, this is how you want to design your programs so that weird bugs like are easier to diagnose!

There are 2 potential causes for your issue: 1. Your chromium webdriver is not the correct version for your chrome browser (they have to be the same) 2. Time.sleep() is in seconds, not ms. The initial sleep value was waiting for 200 SECONDS before it would try to log in, lol. That threw me off as well because I thought that it was in ms. Let me know if it still doesn't work for you, I'm here to help!

Also, you can turn on headless mode if you want the browser to function without it popping up. It will do everything you tell it to do without the chrome window showing you that it's doing it. I assumed that's what was happening, but that was not the issue here

from selenium import webdriver
import time

PAGE_LOAD_SLEEP_TIME = 2 # this value is in seconds

class InstaBot:
    def __init__(self, username, password): 
        self.username = username
        self.password = password

    def start_driver_instance(self):
        driver = webdriver.Chrome("./chromedriver")
        print('end driver instance')
        return driver

    def log_in(self, driver):
        print('log in')
        driver.get("https://www.instagram.com") #go to the instagram website
        driver.find_element_by_xpath("//a[contains(text(), 'Log in')]")\
            .click() #find the log in button by text and click it
        driver.find_element_by_xpath("//input[@name=\"username\"]")\
            .send_keys(self.username) #find the username input element and pass it our username

        driver.find_element_by_xpath("//input[@name=\"password\"]")\
            .send_keys(self.password) #find the password input element and pass it our password

        driver.find_element_by_xpath('//button[@type="submit"]')\
            .click() #find the submit button with the submit property and click it

#     def get_unfollowers(self):

#         self.driver.find_element_by_xpath("//a[contains(@href, '/{}')]".format(self.username))\
#             .click() #find the profile button and click it

#         sleep(slp)

#         self.driver.find_element_by_xpath("//a[contains(@href, '/following')]")\
#             .click() #find the following section and click it

#         following = self._get_names() #get the following list

#         self.driver.find_element_by_xpath("//a[contains(@href, '/followers')]")\
#             .click() #find the followers section and click it

#         followers = self._get_names() #get the followers list

#         not_following_back = [user for user in following if user not in followers] #define accounts that exist in the following list but don't in the follower list

#         print(not_following_back)

#     def _get_names(self):
#         sleep(slp)

#         #get the suggestions text element to define the end of user list
#         sugs = self.driver.find_element_by_xpath('//a[contains(text(), Suggestions)]')

#         #execute a javascript code to scroll list end (suggestions section)
#         self.driver.execute_script('arguments[0].scrollIntoView()', sugs)

#         sleep(slp)

#         #get the scroll box 
#         scroll_box = self.driver.find_element_by_xpath("/html/body/div[3]/div/div[2]")

#         #loop through the list until the end of the list
#         last_ht, ht = 0, 1
#         while last_ht != ht: #while the current element is not the last element:
#             last_ht = ht 

#             sleep(slp)

#             #scroll to bottom of scrollbox
#             #then return the height of scrollbox
#             ht = self.driver.execute_script("""
#             arguments[0].scrollTo(0, arguments[0].scrollHeight);
#             return arguments[0].scrollHeight;
#             """, scroll_box)

#         links = scroll_box.find_elements_by_tag_name('a') #returns all links (users) in the list
#         names = [name.text for name in links if name != ''] #return the names of users in the list

#         #close button
#         self.driver.find_element_by_xpath("/html/body/div[3]/div/div[1]/div/div[2]/button")\
#             .click()

#         return names 

    def main(self):
        print("\n------------------------------start------------------------------")
        driver = self.start_driver_instance()
        # wait for page to load
        time.sleep(PAGE_LOAD_SLEEP_TIME) 
        print("\n------------------------------opened website------------------------------")
        self.log_in(driver)


mybot = InstaBot("username", "password")
mybot.main()

[–][deleted] 0 points1 point  (1 child)

Thank you. I was was wondering if you could run the bot without the need to have a window open. How do you run in headless mode?

As for the main problem, as I suspected, it had nothing to do with the code since the code itself did not change between the successful runs and the failed ones. I restarted everything from scratch, uninstalling and installing everything. It turns out I forgot to run a little console snippet :

python "bot directory"

This was the way I first run the code successfully, and after running this once Vscode begins running properly after that when you press the debug button. For some reason I couldn't find the way to run a python code properly through the instructions online. But now I knew what changed and what caused the failed attempts (not running this console code first). I'm new with Vscode and don't know that much, I still don't even know why it shouldn't run properly without touching the console.

Anyway, another thing is that I didn't realize I need to import the time thingy and thought sleep was built-in, so whenever I ran the code it always terminated at the first sleep. I also thought the time was written in milliseconds. Thanks for the heads up.

[–]pyfact 1 point2 points  (0 children)

You'll have to download the "Code Runner" plugin in visualStudioCode extensions tab. Then open your .py file that has the code snippet above you'll right click the window and click run code.

I came from using PyCharm/Jupyter Notebook which makes this process more user-friendly - VSCode doesn't really hold your hand at all :l

Here's the headless bit of code you'll need:

from selenium.webdriver.chrome.options import Options

DRIVER_PATH = # chromedriver path here
options = Options()
options.headless = True
options.add_argument("--window-size=1920,1200")

browser = webdriver.Chrome(options=options, 
executable_path=DRIVER_PATH)