def post_hashtags_are_sfw(self, browser, log_path, timeout=5): if self.running(): all_hashtags = [ "#" + x for x in self.extract_hash_tags( browser=browser, log_path=log_path, timeout=timeout) ] for hashtag in all_hashtags: if hashtag in Config.nsfw_hashtags: Log.update( screenshot_path=self.screenshot_path, browser=self.browser, log_path=self.log_path, text="This post contains the blacklisted hashtag {}.". format(hashtag), ) return False Log.update( screenshot_path=self.screenshot_path, browser=self.browser, log_path=self.log_path, text= "This post contains none of the blacklisted hashtags. (Hashtags: {})" .format(", ".join(all_hashtags)), ) return True
def like(self, browser, log_path, topic, timeout=5): if self.running(): author = self.author(browser=browser, log_path=log_path) try: WebDriverWait(browser, timeout).until( ec.presence_of_element_located( (By.XPATH, Config.like_button_xpath))) like_button = WebDriverWait(browser, timeout).until( ec.element_to_be_clickable( (By.XPATH, Config.like_button_xpath))) except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in like') return like_button.click() src = self.extract_picture_source(browser=browser, log_path=log_path) Log.update(self.screenshot_path, self.browser, log_path, "Liked picture/video by: " + author, image=src) self.update_action_list(author=author, action_type="like", topic=topic)
def comment(self, topic, browser, log_path, timeout=5): if self.running(): author = self.author(browser=browser, log_path=log_path) query = Config.comments[randint(0, len(Config.comments) - 1)] say = query.format( author, Config.smileys[randint(0, len(Config.smileys) - 1)]) try: WebDriverWait(browser, timeout).until( ec.presence_of_element_located( (By.XPATH, Config.comment_xpath))) WebDriverWait(browser, timeout).until( ec.element_to_be_clickable( (By.XPATH, Config.comment_xpath))) comment_button = WebDriverWait(browser, timeout).until( ec.element_to_be_clickable( (By.XPATH, Config.comment_submit_xpath))) except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in comment') return comment_button.click() comment_field = browser.find_element_by_xpath(Config.comment_xpath) comment_field.send_keys(say) comment_field.send_keys(Keys.RETURN) Log.update( self.screenshot_path, self.browser, log_path, "Commented on " + str(author) + "s picture with: " + say) self.update_action_list(author=author, action_type="comment", topic=topic)
def already_liked(self, browser, log_path, error_timeout=5): if self.running(): try: WebDriverWait(browser, error_timeout).until( ec.presence_of_element_located( (By.XPATH, Config.like_button_full_xpath))) except TimeoutException: return False Log.update(self.screenshot_path, self.browser, log_path, 'Post was already liked.') return True
def author(self, browser, log_path, timeout=5): if self.running(): try: author_element = WebDriverWait(browser, timeout).until( ec.presence_of_element_located( (By.XPATH, Config.author_xpath))) except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in author') return return str(author_element.get_attribute("title"))
def open_unfollow_screen(self, browser, log_path, timeout=15): if self.running(): try: WebDriverWait(browser, timeout).until( ec.presence_of_element_located( (By.XPATH, Config.following_xpath))) heart = WebDriverWait(browser, timeout).until( ec.element_to_be_clickable( (By.XPATH, Config.following_xpath))) except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in open_unfollow_screen') return heart.click()
def monitor(request): if not request.user.is_authenticated: return try: n = int(request.GET['n']) except (MultiValueDictKeyError, ValueError): n = 20 try: search = request.GET['search'] except (MultiValueDictKeyError, ValueError): search = '' if not request.user.is_authenticated: return path = "static/img/" + request.user.username + "/screenshot.png" try: time = os.path.getmtime(path) except FileNotFoundError: time = 0 src = path + "?mtime=" + str(time) # pages = range(Log.number_of_pages(page_size=page_size)) username = request.user.username log_path = Config.bot_path + "log/" + username path = log_path + "/log.pickle" lines = Log.get(log_path=path, page_size=n, search=search) return render(request, 'monitor.html', {'lines': lines, 'src': src})
def unfollow(self, browser, log_path, name, timeout=5): if self.running(): browser.get("https://www.instagram.com/" + name + "/") try: WebDriverWait(browser, timeout).until( ec.presence_of_element_located( (By.XPATH, Config.unfollow_xpath))) unfollow_button = WebDriverWait(browser, timeout).until( ec.element_to_be_clickable( (By.XPATH, Config.unfollow_xpath))) except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in unfollow') return unfollow_button.click() Log.update(self.screenshot_path, self.browser, log_path, "Unfollowed: " + name)
def extract_picture_source(self, browser, log_path, timeout=5): if self.running(): try: WebDriverWait(browser, timeout).until( ec.presence_of_element_located( (By.XPATH, Config.image_div_container_xpath))) sections = browser.find_elements_by_xpath( Config.image_div_container_xpath) except NoSuchElementException: Log.update( self.screenshot_path, self.browser, log_path, 'Exception in extract_picture_source: ' + str(format_exc())) return except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in extract_picture_source') return for section in sections: try: image = section.find_element_by_tag_name("img") except NoSuchElementException: Log.update( self.screenshot_path, self.browser, log_path, 'Exception in extract_picture_source: ' + str(format_exc())) return return image.get_attribute("src")
def extract_hash_tags(self, browser, log_path, timeout=5): if self.running(): try: WebDriverWait(browser, timeout).until( ec.presence_of_element_located( (By.XPATH, Config.hashtags_xpath))) sections = browser.find_elements_by_xpath( Config.hashtags_xpath) except NoSuchElementException: Log.update( self.screenshot_path, self.browser, log_path, 'Exception in extract_hash_tags: ' + str(format_exc())) return [] except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in extract_hash_tags') return [] all_hashtags = [] for section in sections: all_hashtags.extend( set(part[1:] for part in section.text.split() if part.startswith('#'))) return all_hashtags
def follow(self, browser, log_path, topic, timeout=15): if self.running(): author = self.author(browser=browser, log_path=log_path) try: WebDriverWait(browser, timeout).until( ec.presence_of_element_located( (By.XPATH, Config.follow_xpath))) follow_button = WebDriverWait(browser, timeout).until( ec.element_to_be_clickable( (By.XPATH, Config.follow_xpath))) except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in follow') return follow_button.click() Log.update(self.screenshot_path, browser=self.browser, log_path=self.log_path, text="Followed: " + author) self.update_action_list(author=author, action_type="follow", topic=topic) self.update_accounts_to_unfollow(author=author) self.update_followed_accounts(author=author)
def select_first(self, browser, log_path, timeout=5): if self.running(): try: WebDriverWait(browser, timeout).until( ec.presence_of_element_located( (By.XPATH, Config.first_ele_xpath))) pictures = browser.find_elements_by_xpath( Config.first_ele_xpath) except NoSuchElementException: Log.update( self.screenshot_path, self.browser, log_path, 'NoSuchElementException in select_first: ' + str(format_exc())) return except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in select_first') return if len(pictures) > 9: first_picture = pictures[9] else: first_picture = pictures[len(pictures) - 1] self.focus(first_picture, browser=browser) first_picture.click()
def post_is_sfw(self, browser, log_path, limit=0.1): if self.running(): if not self.post_hashtags_are_sfw(browser=browser, log_path=log_path): return False image_url = self.extract_picture_source(browser=browser, log_path=log_path) if not image_url: Log.update(screenshot_path=self.screenshot_path, browser=self.browser, log_path=self.log_path, text="Picture source could not be extracted.") return True sfw, nsfw = classify_nsfw(image_url) Log.update( screenshot_path=self.screenshot_path, browser=self.browser, log_path=self.log_path, text="Analysis of this post yielded it to be {}% SFW.".format( int(100 * sfw)), image=image_url) return nsfw < limit
def table_monitor_update(request): if not request.user.is_authenticated: return try: n = int(request.GET['n']) except (MultiValueDictKeyError, ValueError): n = 20 try: search = request.GET['search'] except (MultiValueDictKeyError, ValueError): search = '' username = request.user.username log_path = Config.bot_path + "log/" + username path = log_path + "/log.pickle" lines = Log.get(log_path=path, page_size=n, search=search) return render(request, 'table_monitor_update.html', {'lines': lines})
def login(self, username, password, browser, log_path, timeout=5): if self.running(): Log.update(self.screenshot_path, self.browser, log_path, "Logging in") browser.get(Config.start_url) try: username_field = WebDriverWait(browser, timeout).until( ec.presence_of_element_located((By.NAME, "username"))) pass_field = WebDriverWait(browser, timeout).until( ec.presence_of_element_located((By.NAME, "password"))) except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in login') return username_field.send_keys(username) pass_field.send_keys(password) pass_field.send_keys(Keys.RETURN) Log.update(self.screenshot_path, self.browser, log_path, "Logged in")
def check_follows(self, browser, log_path, timeout=15): if self.running(): try: WebDriverWait(browser, timeout).until( ec.presence_of_element_located( (By.XPATH, Config.sections_xpath))) sections = browser.find_elements_by_xpath( Config.sections_xpath) except NoSuchElementException: Log.update( self.screenshot_path, self.browser, log_path, 'NoSuchElementException in check_follows: ' + str(format_exc())) return except TimeoutException: Log.update(self.screenshot_path, self.browser, log_path, 'Timeout in check_follows') return users = [] for element in sections: try: profile = element.find_element_by_xpath( Config.local_name_xpath) except NoSuchElementException: Log.update( self.screenshot_path, self.browser, log_path, 'NoSuchElementException in check_follows: ' + str(format_exc())) return name = profile.get_attribute("title") users.append(name) for user in users: if user not in self.interacting_users: if user in self.action_list.keys(): actions = self.action_list[user] for action in actions: self.hashtags[action["topic"]] += 1 self.update_interacting_users(user=user)
def run(self): self.login(browser=self.browser, log_path=self.log_path, password=self.password, username=self.username) while self.running(): try: self.open_unfollow_screen(browser=self.browser, log_path=self.log_path) self.check_follows(browser=self.browser, log_path=self.log_path) top_hashtags = sorted(self.hashtags.keys(), key=lambda k: self.hashtags[k], reverse=True)[:20] for i, topic in enumerate(top_hashtags): self.search(query=topic, browser=self.browser, log_path=self.log_path) self.select_first(browser=self.browser, log_path=self.log_path) delay, action = self.dispatcher.next_action() Log.update( self.screenshot_path, self.browser, self.log_path, "Dispatcher selected action: {} (Sleeping {}s)".format( action, delay)) sleep(delay) if action == "comment": if self.post_is_sfw(browser=self.browser, log_path=self.log_path): self.comment(topic=topic, browser=self.browser, log_path=self.log_path) self.dispatcher.log_action("comment") self.store_hashtags(browser=self.browser, log_path=self.log_path) elif action == "like": count = 0 while self.already_liked(browser=self.browser, log_path=self.log_path): if not self.on_dialog_page(self.browser, self.log_path): break if count > 10: break self.next_picture(browser=self.browser) count += 1 if self.on_dialog_page(self.browser, self.log_path): if self.post_is_sfw(browser=self.browser, log_path=self.log_path): self.like(topic=topic, browser=self.browser, log_path=self.log_path) self.dispatcher.log_action("like") self.store_hashtags(browser=self.browser, log_path=self.log_path) elif action == "follow": count = 0 while self.user_followed_already( self.author(browser=self.browser, log_path=self.log_path)): if not self.on_dialog_page(self.browser, self.log_path): break if count > 10: break self.next_picture(browser=self.browser) count += 1 if self.on_dialog_page(self.browser, self.log_path): if self.post_is_sfw(browser=self.browser, log_path=self.log_path): self.follow(topic=topic, browser=self.browser, log_path=self.log_path) self.dispatcher.log_action("follow") self.store_hashtags(browser=self.browser, log_path=self.log_path) elif action == "unfollow": if len(self.accounts_to_unfollow) > 50: this_guy = self.accounts_to_unfollow[0] self.unfollow(name=this_guy, browser=self.browser, log_path=self.log_path) del self.accounts_to_unfollow[0] self.dispatcher.log_action("unfollow") except Exception: Log.update(self.screenshot_path, self.browser, self.log_path, text='General Exception: ' + str(format_exc())) Log.update(self.screenshot_path, self.browser, self.log_path, text='Stopped bot') if self.vdisplay: self.vdisplay.stop() super(Driver, self).join()
def search(self, browser, log_path, query): if self.running(): browser.get("https://www.instagram.com/explore/tags/" + query + "/") Log.update(self.screenshot_path, self.browser, log_path, "Searching for " + query + ".")