Repository: InstaPy/InstaPy

Issue:
interact_user_followers crashes with Message: no such element: Unable to locate element:
```
from instapy import InstaPy

session = InstaPy(username='username', password='password', nogui=True)
session.login()
session.interact_user_followers(['User1'], amount=12, random=True)
session.end()
```

```
Logged in successfully!
Traceback (most recent call last):
  File "test4_instapy.py", line 24, in <module>
    session.interact_user_followers(['User1'], amount=12, random=True)
  File "/virt_uni/InstaPy/instapy/instapy.py", line 849, in interact_user_followers
    userToInteract += get_given_user_followers(self.browser, user, amount, self.dont_include, self.username, self.follow_restrict, random)
  File "/virt_uni/InstaPy/instapy/unfollow_util.py", line 327, in get_given_user_followers
    allfollowing = formatNumber(browser.find_element_by_xpath("//li[2]/a/span").text)
  File "/usr/local/lib/python3.4/dist-packages/selenium/webdriver/remote/webdriver.py", line 293, in find_element_by_xpath
    return self.find_element(by=By.XPATH, value=xpath)
  File "/usr/local/lib/python3.4/dist-packages/selenium/webdriver/remote/webdriver.py", line 752, in find_element
    'value': value})['value']
  File "/usr/local/lib/python3.4/dist-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python3.4/dist-packages/selenium/webdriver/remote/errorhandler.py", line 192, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//li[2]/a/span"}
  (Session info: chrome=61.0.3163.100)
  (Driver info: chromedriver=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),platform=Linux 3.16.0-4-amd64 x86_64)
```


Discussion:

Resolving patch:
diff --git a/instapy/instapy.py b/instapy/instapy.py
--- a/instapy/instapy.py
+++ b/instapy/instapy.py
@@ -843,11 +843,21 @@ def interact_user_followers(self, usernames, amount=10, random=False):
             usernames = [usernames]
         try:
             for user in usernames:
-                userToInteract += get_given_user_followers(self.browser, user, amount, self.dont_include, self.username, self.follow_restrict, random)
+
+                user = get_given_user_followers(self.browser,
+                                                user,
+                                                amount,
+                                                self.dont_include,
+                                                self.username,
+                                                self.follow_restrict,
+                                                random)
+                if type(user) is list:
+                    userToInteract += user
         except (TypeError, RuntimeWarning) as err:
             if type(err) == RuntimeWarning:
                 print(u'Warning: {} , stopping follow_users'.format(err))
-                self.logFile.write('Warning: {} , stopping follow_users\n'.format(err))
+                self.logFile.write(
+                    'Warning: {} , stopping follow_users\n'.format(err))
 
                 return self
             else:
@@ -857,10 +867,15 @@ def interact_user_followers(self, usernames, amount=10, random=False):
 
                 return self
 
-        print('--> Users: {}'.format(len(userToInteract)))
-        print('')
-        userToInteract = sample(userToInteract, int(ceil(self.user_interact_percentage*len(userToInteract)/100)))
-        self.like_by_users(userToInteract, self.user_interact_amount, self.user_interact_random, self.user_interact_media)
+        print('--> Users: {} \n'.format(len(userToInteract)))
+        userToInteract = sample(
+            userToInteract,
+            int(ceil(self.user_interact_percentage*len(userToInteract)/100)))
+
+        self.like_by_users(userToInteract,
+                           self.user_interact_amount,
+                           self.user_interact_random,
+                           self.user_interact_media)
 
         return self
 
diff --git a/instapy/unfollow_util.py b/instapy/unfollow_util.py
--- a/instapy/unfollow_util.py
+++ b/instapy/unfollow_util.py
@@ -320,34 +320,44 @@ def follow_through_dialog(browser, user_name, amount, dont_include, login, follo
 
     return person_followed
 
-def get_given_user_followers(browser, user_name, amount, dont_include, login, follow_restrict, is_random):
-    browser.get('https://www.instagram.com/' + user_name)
 
-    #  check how many poeple are following this user.
-    allfollowing = formatNumber(browser.find_element_by_xpath("//li[2]/a/span").text)
+def get_given_user_followers(browser,
+                             user_name,
+                             amount,
+                             dont_include,
+                             login,
+                             follow_restrict,
+                             is_random):
 
-    #  throw RuntimeWarning if we are 0 people following this user
-    if (allfollowing == 0):
-        raise RuntimeWarning('There are 0 people to follow')
+    browser.get('https://www.instagram.com/' + user_name)
 
+    # check how many poeple are following this user.
+    # throw RuntimeWarning if we are 0 people following this user or
+    # if its a private account
     try:
-        following_link = browser.find_elements_by_xpath('//a[@href="/' + user_name + '/followers/"]')
-        following_link[0].send_keys("\n")
-    except BaseException as e:
-        print("following_link error \n", str(e))
+        allfollowing = formatNumber(
+            browser.find_element_by_xpath("//li[2]/a/span").text)
+    except NoSuchElementException:
+        print ('Can\'t interact with private account')
+        return
+
+    following_link = browser.find_elements_by_xpath(
+        '//a[@href="/' + user_name + '/followers/"]')
+    following_link[0].send_keys("\n")
 
-    followNum = 0
     sleep(2)
-    person_followed = []
 
     # find dialog box
-    dialog = browser.find_element_by_xpath("//div[text()='Followers']/following-sibling::div")
+    dialog = browser.find_element_by_xpath(
+        "//div[text()='Followers']/following-sibling::div")
 
     # scroll down the page
     scroll_bottom(browser, dialog, allfollowing)
 
-    #Get follow buttons. This approch will find the follow buttons and ignore the Unfollow/Requested buttons.
-    follow_buttons = dialog.find_elements_by_xpath("//div/div/span/button[text()='Follow']")
+    # get follow buttons. This approch will find the follow buttons and
+    # ignore the Unfollow/Requested buttons.
+    follow_buttons = dialog.find_elements_by_xpath(
+        "//div/div/span/button[text()='Follow']")
     person_list = []
 
     if amount >= len(follow_buttons):
@@ -365,7 +375,8 @@ def get_given_user_followers(browser, user_name, amount, dont_include, login, fo
     for person in finalBtnPerson:
 
         if person and hasattr(person, 'text') and person.text:
-            person_list.append(person.find_element_by_xpath("../../../*").find_elements_by_tag_name("a")[1].text)
+            person_list.append(person.find_element_by_xpath(
+                "../../../*").find_elements_by_tag_name("a")[1].text)
 
     return person_list
 


Test patch: