I'm learning about selenium on python and came across an error I don`t really know how to solve:
In this project the bot I've designed was supossed to Like all the tweets on the page when I searched for a certain subject. Altought the bot go through all the loops and like half of the tweets, it still misses every 2 or 3 tweets. Could somebody shed a light on why is it missing tweets?
# it's essencial that the user first pip install selenium on his system or on the source code editor such as visual code
# afterwards download the latest geckodriver on github and unzip it on the root of your python folder
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
class TwitterBot:
def __init__(self,username,password):
self.username = username
self.password = password
self.bot = webdriver.Firefox()
def login(self):
bot = self.bot
bot.get('https://twitter.com/login')
time.sleep(5) # I used a timer to load wait for the page to load before entering the login and password
email = bot.find_element_by_name("session[username_or_email]")
password = bot.find_element_by_name("session[password]")
email.clear()
password.clear()
email.send_keys(self.username)
password.send_keys(self.password)
password.send_keys(Keys.RETURN)
time.sleep(5)
def like_tweet(self,hashtag):
bot = self.bot
bot.get('https://twitter.com/search?q='+hashtag+'&src=typeahead_click')
time.sleep(3)
bot.find_element_by_link_text("Latest").click()
time.sleep(3)
for i in range(6):
bot.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(3)
tweets = bot.find_elements_by_xpath('//div[#data-testid="tweet"]')
for tweet in tweets:
try:
bot.find_element_by_xpath('//div[#data-testid="like"]').click()
time.sleep(3)
except:
print("ERROR")
bot = TwitterBot('xxx#gmail.com','xxxxx') # Enter here your username/e-mail and password like this: ('email#email.com','password')
bot.login()
bot.like_tweet('python learning') # Enter here the subject you want the bot to search for ('subject')
Related
So I do realize that using gmail api is the best solution, but due to the gmail account having restrictions (school) I can't actually use the api. So while I was searching for the solution I have found about selenium.
I haven't actually found a tutorial about how to filter emails/click on emails that is within 24 hours (which I think I can set it up myself) and click on emails with an link attached (google.meet)
Since the subject isn't always the same nor the sender, I can't actually limit it to the subject and email, so need help with some kind of email body filter.
import webbrowser
from selenium import webdriver
import time
import email
import imaplib
import sys
import datetime
import smtplib
with open('accountdetail.txt', 'r') as file:
for details in file:
username,password = details.split(':')
# create a new Chrome session
driver = webdriver.Chrome('C:\driver\chromedriver.exe')
driver.implicitly_wait(30)
driver.maximize_window()
# navigate to the application home page
driver.get("https://accounts.google.com/")
#get the username textbox
login_field = driver.find_element_by_name("identifier")
login_field.clear()
#enter username
login_field.send_keys(username)
login_field.send_keys(u'\ue007') #unicode for enter key
time.sleep(4)
#get the password textbox
password_field = driver.find_element_by_name("password")
password_field.clear()
#enter password
password_field.send_keys(password)
password_field.send_keys(u'\ue007') #unicode for enter key
time.sleep(10)
#navigate to gmail
driver.get("https://mail.google.com/")
I have found this resources, but for some reason they only work with subject and doesn't actually click on email with a link.
How to click on a Particular email from gmail inbox in Selenium?
https://www.youtube.com/watch?v=6VJaWtz6kzs
If you have the exact link, you can get the element using XPath and click:
url = r'YOUR URL, FROM ANY VARIABLE'
driver.find_element_by_xpath('//a[#href="'+url+'"]').click()
This is my code:
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# loading the webpage
browser = webdriver.Chrome()
browser.get("https://instagram.com")
time.sleep(1)
# finding essential requirements
user_name = browser.find_element_by_name("username")
password = browser.find_element_by_name("password")
login_button = browser.find_element_by_xpath("//button [#type = 'submit']")
# filling out the user name box
user_name.click()
user_name.clear()
user_name.send_keys("username")
# filling out the password box
password.click()
password.clear()
password.send_keys("password")
# clicking on the login button
login_button.click()
time.sleep(3)
# information save permission denial
not_now_button = browser.find_element_by_xpath("//button [#class = 'sqdOP yWX7d y3zKF ']")
not_now_button.click()
time.sleep(3)
# notification permission denial
not_now_button_2 = browser.find_element_by_xpath("//button [#class = 'aOOlW HoLwm ']")
not_now_button_2.click()
time.sleep(3)
# finding search box and searching + going to the page
search_box = browser.find_element_by_xpath('//input [#placeholder="Search"]')
search_box.send_keys("sb else's page")
time.sleep(3)
search_box.send_keys(Keys.RETURN)
search_box.send_keys(Keys.RETURN)
time.sleep(3)
# opening ((followers)) list
followers = browser.find_element_by_xpath('//a [#class="-nal3 "]')
followers.click()
time.sleep(10)
# following each follower
follower = browser.find_elements_by_xpath('//button [#class="sqdOP L3NKy y3zKF "]')
browser.close()
In this code, I normally simulate what a normal person does to follow another person.
I want to follow each follower of a page. I have thought all day long; But couldn't find any algorithms.
Got some good ideas, but just realized I don't know how I can scroll down to the end of the list to get the entire list. Can you help? (If you don't get me, try running the code and then extract the list of followers.)
# following each follower
get list of followers
for each follower - click 'follow' if it's possible
if button text haven't changed, it means that you reached the limit of follows, or maybe banned
Also, be sure to limit your actions, instagram had limit of follows (30 per hour, it was before)
And you can get the followers directly through instagram API.
And don't forget to unfollow them, because unfollowing also has limits. And the limit of current follows is 7500( it was before, not sure how about now)
First you need to get a list of the users that follows someone, then you just execute the same code in a loop. You can either scrape the users separate, or within selenium. Then run the code needed to follow a given person, in Ex. a for loop. Step 6: profit
I posted recently about some trouble I was having with selenium, primarily the anticaptcha API. Ive managed to solve that but I am having some trouble over here. This is my current code:
from time import sleep
from selenium import webdriver
from python_anticaptcha import AnticaptchaClient, NoCaptchaTaskProxylessTask
import os
import time
#Gather Api Key
api_key = 'INSERT API KEY HERE'
#Go to the acc registration site
browser = webdriver.Chrome()
browser.implicitly_wait(5)
browser.get('https://www.reddit.com/register/')
sleep(2)
#Input email
email_input = browser.find_element_by_css_selector("input[name='email']")
email_input.send_keys("INSERT EMAIL HERE")
#Continue to the next part of the registration process
continue_button = browser.find_element_by_xpath("//button[#type='submit']")
continue_button.click()
#Find and input the username and password fields
username_input = browser.find_element_by_css_selector("input[name='username']")
password_input = browser.find_element_by_css_selector("input[name='password']")
username_input.send_keys("INSERT USERNAME HERE")
password_input.send_keys("INSERT PASSWORD HERE")
#Gather site key
url = browser.current_url
site_key = "6LeTnxkTAAAAAN9QEuDZRpn90WwKk_R1TRW_g-JC"
#Acc do the solving process
client = AnticaptchaClient(api_key)
task = NoCaptchaTaskProxylessTask(url, site_key)
job = client.createTask(task)
print("Waiting for recaptcha solution")
job.join()
# Receive response
response = job.get_solution_response()
print(response)
print("Solution has been gotted")
# Inject response in webpage
browser.execute_script('document.getElementById("g-recaptcha-response").innerHTML = "%s"' % (response))
print("Injecting Solution")
# Wait a moment to execute the script (just in case).
time.sleep(1)
print("Solution has been gotted for sure")
# Press submit button
browser.implicitly_wait(10)
Signup = browser.find_element_by_xpath('//input[#type="submit"]')
Signup.click()
Everything runs smoothly except for the final line. I think the program is recognizing the submit button but for some reason gives an element not interactable error. Any help on how to solve this would be greatly appreciated
I had the same issue when I was using selenium. Sometimes it happens that even though selenium has recognized the element, its function is not "ready." Adding a delay before clicking the submit button should fix the issue.
This question already has answers here:
selenium python send_key error: list object has no attribute
(9 answers)
Closed 3 years ago.
I am making a Twitter bot that can automatically login when I run the script. But whenever I run the script, I get this an error that I cannot find any solutions for. Does anyone have an idea of how to fix it?
I tried to change element to elements and send_keys to send_Keys but it won't work
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
class TwitterBot:
def __init__(self,username,password):
self.username = username
self.password = password
self.bot = webdriver.Firefox()
def login(self):
bot = self.bot
bot.get('https://twitter.com/')
time.sleep(3)
email = bot.find_elements_by_class_name('email-input')
password = bot.find_elements_by_class_name('session[password]')
email.clear()
password.clear()
email.send_keys(self.username)
password.send_keys(self.password)
password.send_keys(Keys.RETURN)
ed = TwitterBot('EMAIL HERE', 'PASSWORD HERE')
ed.login()
I hope to get it logging in so I can work further on my project.
find_elements_by_xxx will return list of elements and you can't perform the send_keys operation on the list. Instead you have to use find_element_by_xxx which will return a single element, then you can perform element based operations.
If you want to get the list of element and then perform the operation on any specific element then you can use below logic.
elements = driver.find_elements_by_xxx("locator")
# perform operation on the first matching element
elements[0].send_keys("value_goes_here")
# if you want to perform operation on the last matching element
element[-1].send_keys("value_goes_here")
I now know what I messed up:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
class TwitterBot:
def __init__(self,username,password):
self.username = username
self.password = password
self.bot = webdriver.Firefox()
def login(self):
bot = self.bot
bot.get('https://twitter.com/')
time.sleep(3)
email = bot.find_element_by_name('session[username_or_email]')
password = bot.find_element_by_name('session[password]')
email.clear()
password.clear()
email.send_keys(self.username)
password.send_keys(self.password)
ed = TwitterBot('EMAIL HERE', 'PASSWORD HERE')
ed.login()
On the line email = bot.find_element_by_name('session[username_or_email]')
it was first bot.find_element_by_class_name('session[username_or_email]')
Feeling stupid. Thanks for the help guys!
Has anyone faced the problem that automation routine for instagram written in python with selenium chromedriver has become difficult to run recently because instagram keeps asking for the code it sends in sms or email?
When you do your normal browser login it asks for the code in sms only once. But when you do it with selenium it asks for it every time.
Here is the code
options = webdriver.ChromeOptions()
#options.add_argument('headless')
#options.add_argument('--headless')
options.add_argument('--disable-logging')
options.add_argument('--log-level=3')
driver = webdriver.Chrome(chrome_options=options)
#driver = webdriver.Chrome()
print('Driver started successfully!')
driver.get("https://instagram.com/")
time.sleep(6)
pg=driver.find_element_by_tag_name("html")
lng=pg.get_attribute("lang")
#print(lng)
if lng=='en':
global lin
global foll
global foll_tx
global subscr_tx
lin="Log in"
foll="followers"
foll_tx="Follow"
subscr_tx="following"
get_enter_bt
= driver.find_elements_by_link_text(self.lin)
lin_found=False
while not lin_found:
if len(get_enter_bt)==0:
print('Login not found ((( Refreshing...')
driver.refresh()
time.sleep(6)
get_enter_bt = driver.find_elements_by_link_text(self.lin)
else:
lin_found=True
print('Login button found!')
time.sleep(3)
get_enter_bt[0].click()
time.sleep(3)
#login
login = driver.find_element_by_name("username")
login.send_keys(username)
login = driver.find_element_by_name("password")
login.send_keys(password)
login.send_keys(Keys.RETURN)
time.sleep(9)
get_close_mobapp=driver.find_elements_by_css_selector("button._dbnr9")
if len(get_close_mobapp)!=0:
get_close_mobapp[0].click()
notif_switch=driver.find_elements_by_css_selector("button.aOOlW.HoLwm")
print('notif butt %s' % len(notif_switch))
if len(notif_switch)>0:
notif_switch[0].click()
print(1)
#detect suspicious login
susp_login_msg=driver.find_element_by_xpath("//*[#id=\"react-root\"]/section/div/div/div[1]/div/p")#<p class="O4QwN">Подозрительная попытка входа</p>
print('susm login msg %s' % (susp_login_msg!=None))
if susp_login_msg:
if susp_login_msg.text=='Подозрительная попытка входа':
try:
mobile_button = driver.find_element_by_xpath("//*[#id=\"react-root\"]/section/div/div/div[3]/form/div/div[2]/label")
mobile_button.click()
except:
mobile_button = driver.find_element_by_xpath("//*[#id=\"react-root\"]/section/div/div/div[3]/form/div/div[1]/label")
mobile_button.click()
snd_code_btn=driver.find_element_by_xpath("//*[#id=\"react-root\"]/section/div/div/div[3]/form/span/button")
snd_code_btn.click()
print('Instagram detected an unusual login attempt')
print('A security code was sent to your mobile '+mobile_button.text)
security_code = input('Type the security code here: ')
#security_code_field = driver.find_element_by_xpath(("//input[#id='security_code']"))
security_code_field.send_keys(security_code)
‐----‐‐‐----
This code works fine, but how to stop instagram from asking for the code in sms every time? Does it detect that I run selenium and runs a kind of antibot activity?
I was running the script on schedule to perform series of likes for my subscribers for example which is time consuming you know and automation was my remedy)))