selenium ,how to send emoji to sender in whatsapp with send_keys()? - python

selenium ,how to send emoji to sender in WhatsApp with send_keys()? . i dont want to send emoji by clicking on that emoji button ,but i want to like just copy the emoji which has been sent to us in text message of whatsapp and send that same emoji to sender . i have tried this as helped by #cruisepandey
chats = driver.find_elements_by_css_selector("img[data-plain-text][crossorigin='anonymous']")
for chat in chats:
print(chat.get_attribute('alt'))
this above code prints all the emojis of a chat. But by using this code this gives an error of
chats = driver.find_elements_by_css_selector("img[data-plain-text][crossorigin='anonymous']")
for chat in chats:
print(chat.get_attribute('alt'))
type = driver.find_element_by_xpath('//div[#data-tab="6"]')
type.send_keys(chat.get_attribute('alt'))
this code gives an error = Message: unknown error: ChromeDriver only supports characters in the BMP
chats = driver.find_elements_by_css_selector("img[data-plain-text][crossorigin='anonymous']")
for chat in chats:
print(chat.get_attribute('alt'))
type = driver.find_element_by_xpath('//div[#data-tab="6"]')
pyperclip.copy(chat.get_attribute('alt'))
type.send_keys(Keys.CONTROL + "V")
time.sleep(1)
i tried this code to send emoji but this by using this actually it works but it sends twice in whatsapp typebar but prints only once in terminal for a particular emoji for eg it prints this in terminal "🔥" and same code types this in whatsapp typebar "🔥🔥" . CAN ANYONE HELP ME WHY IT IS PRINTING TWICE IN WHATSAPP TYPEBAR BUT ONLY ONCE IN TERMINAL ??? i also want to append that emoji into a list ,but when appending that emojis ,after printing list ,it gives a list with elements ="None" . This is complete code
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
import time
import pyperclip
driver = webdriver.Chrome(r'C:\Users\PRANAV PATIL\Downloads\chromedriver.exe')
driver.get(r'https://web.whatsapp.com/')
searchbox = WebDriverWait(driver,
10).until(expected_conditions.presence_of_element_located((By.XPATH,
"//div[#id='side']//div//div//label//div//div[#contenteditable='true']")))
searchbox.send_keys('') #enter your sender's name
searchbox.send_keys(Keys.RETURN)
time.sleep(2)
chats = driver.find_elements_by_css_selector("img[data-plain-text][crossorigin='anonymous']")
for chat in chats:
print(chat.get_attribute('alt'))
type = driver.find_element_by_xpath('//div[#data-tab="6"]')
pyperclip.copy(chat.get_attribute('alt'))
type.send_keys(Keys.CONTROL + "V")
time.sleep(1)

Regarding that typing twice : Instead of type.send_keys(Keys.CONTROL + "V"), try like below. It worked for me.
type.send_keys(Keys.CONTROL+"v")

So basically, you want to send_keys to type
Did you try this :
type = driver.find_element_by_xpath('//div[#data-tab="6"]')
type.send_keys(chat.get_attribute('alt'), Keys.RETURN)
Update 1 :
Looks like you cannot simply send special character like emoji to chromedriver, try changing your browser (change to Firefox and see if that helps) should help you past this issue.
also, if you wanna stick with Chrome, you can give it a try like this :
JS_ADD_TEXT_TO_INPUT = """
var elm = arguments[0], txt = arguments[1];
elm.value += txt;
elm.dispatchEvent(new Event('change'));
"""
type = driver.find_element_by_xpath('//div[#data-tab="6"]')
driver.execute_script(JS_ADD_TEXT_TO_INPUT, type, chat.get_attribute('alt'))
Update 2 :
Using FireFox :
driver = webdriver.Firefox(executable_path = "D:\geckodriver.exe")
driver.maximize_window()
driver.implicitly_wait(30)
driver.get("https://web.whatsapp.com/")
wait = WebDriverWait(driver, 20)
try:
searchbox = WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div[class*='copyable-text selectable-text']")))
searchbox.send_keys('Anvesh') # enter your sender's name
searchbox.send_keys(Keys.RETURN)
print('search was successful')
except:
print('there were some error while searching for name')
pass
time.sleep(2)
chats = driver.find_elements_by_css_selector("img[data-plain-text][crossorigin='anonymous']")
for chat in chats:
print(chat.get_attribute('alt'))
type = driver.find_element_by_xpath('//div[#data-tab="6"]')
type.send_keys(chat.get_attribute('alt'))
time.sleep(1)

Related

Open whatsapp on a headless browser

Use case:
Sending out automated WhatsApp messages using pythonanywhere. Step by step logic below:
non-coders write on a gsheet the phone numbers to which we should
send out the messages
the gsheet data is read (using gspread in pythonanywhere)
open WhatsApp URL to send out the messages in bulk
I have a code using selenium running on my machine that opens the web whatsapp url, finds the needed elements on the website, and sends the messages to the gsheets phone numbers - find below a snippet from that part of the code that I am using on my machine:
global driver
driver.get('https://web.whatsapp.com/')
waiter.until(EC.title_is("WhatsApp"))
waitCounter = 0
while 1:
try:
waiter.until(EC.presence_of_element_located((By.XPATH, "//canvas[#aria-label='Scan me!']")))
waitCounter+=1
if waitCounter%1000 == 0:
print("Waiting for user to log in...", 'WARNING')
except:
print("Logged in to WhatsApp")
break
for entry in data:
driver.find_element_by_xpath(PHONE_NUMER_INPUT).send_keys(str(entry['PhoneNumber']))
time.sleep(2)
driver.find_element_by_xpath(PHONE_NUMER_INPUT).send_keys(Keys.ENTER)
time.sleep(2)
driver.find_element_by_class_name('p3_M1').send_keys(str(entry['Message']))
time.sleep(2)
driver.find_element_by_class_name('_4sWnG').click()
time.sleep(2)
Doubt:
To make step nr 3. working on python anywhere I would have to use a headless browser. However, to initiate whatsapp web we always need to do the QR code scan, so I am not being able to do it that way. Find below the current (useless) part of my code with the headless selenium code - (NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id='side']/div[1]/div/label/div/div[2]"}). I am quite stuck here. Any tip or idea to overcome this is more than welcome and happy to discuss any possible solutions using other libraries that you guys might find appropriate.
Thanks in advance.
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--disable-gpu")
driver = webdriver.Chrome(options=chrome_options)
def send_whatsapp_message():
global driver
driver.get('https://web.whatsapp.com/')
print("Done updating, check the spreadsheet now")
#redirect('https://web.whatsapp.com/', code=302)
for entry in data:
driver.find_element_by_xpath("//*[#id='side']/div[1]/div/label/div/div[2]").send_keys(str(entry['PhoneNumber']))
time.sleep(2)
driver.find_element_by_xpath("//*[#id='side']/div[1]/div/label/div/div[2]").send_keys(Keys.ENTER)
time.sleep(2)
driver.find_element_by_class_name('p3_M1').send_keys(str(entry['Message']))
time.sleep(2)
driver.find_element_by_class_name('_4sWnG').click()
time.sleep(2)
print("Successfully send message to {0}, name: {1}".format(str(entry['PhoneNumber']), str(entry['Name'])), 'INFO')

twitter bot selenium not liking all tweets on the page

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')

Retrieve message from DOM with Selenium

I am learning Python and I am trying things with Selenium. Today I am trying to retrieve a message from the Spectrum chat of Star Citizen: https://robertsspaceindustries.com/spectrum/community/SC/lobby/1
I would like to retrieve the: div class="lobby-motd-message" because it gives good information.
This is my code but when I run it, it displays nothing... Can you help me to solve this problem ? Please. I will do more things with Selenium ( a Discord bot) but I need to retrieve this information first.
#!/usr/bin/python3
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
opts = Options()
opts.headless = True
browser = webdriver.Firefox(options=opts)
url = "https://robertsspaceindustries.com/spectrum/community/SC/lobby/1"
browser.get(url)
browser.implicitly_wait(10)
try:
info = browser.find_element_by_class_name("lobby-motd-message")
print(info.text)
except:
print("not found")
browser.close()
quit()
Depending on what element you want you might need to target and get it's text.
try:
info = browser.find_element_by_class_name("lobby-motd-message")
print(info.find_element_by_tag_name('p').text)
except:
print("not found")
Outputs
Star Citizen Alpha 3.11 is LIVE - Discover more here !
All of it
print(info.get_attribute('innerHTML'))
Outputs
<p>Star Citizen Alpha 3.11 is LIVE - Discover more here !</p>

Selenium submit button element not interactable

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.

Sending emojis with selenium's send_keys()

I would like to send a :heart: emoji with selenium's send_keys()
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Chrome('./chromedriver')
driver.get("https://web.whatsapp.com/")
wait = WebDriverWait(driver, 600)
message = driver.find_elements_by_xpath('//*[#id="main"]/footer/div[1]/div[2]/div/div[2]')[0]
message.send_keys(":heart:")
However, this does not work and sends a string ':heart:'.
Could you please suggest how to do it correctly?
Well,
Here is a workaround! Hope it works!
text_element = driver_trader.find_element_by_xpath('xpath')
text = '⚪📢😆'
driver.execute_script("arguments[0].innerHTML = '{}'".format(text),text_element)
text_element .send_keys('.')
text_element .send_keys(Keys.BACKSPACE)
Here is a tricky way. we can take help of JavaScript and then driver.execute_script that JS code. You can use this function to do that:
from selenium import webdriver
from selenium.webdriver.common.by import By
import chromedriver_autoinstaller
chromedriver_autoinstaller.install()
driver = webdriver.Chrome()
def paste_content(driver, el, content):
driver.execute_script(
f'''
const text = `{content}`;
const dataTransfer = new DataTransfer();
dataTransfer.setData('text', text);
const event = new ClipboardEvent('paste', {{
clipboardData: dataTransfer,
bubbles: true
}});
arguments[0].dispatchEvent(event)
''',
el)
# Go to a page
driver.get('https://some-random-site-as-you-wish.com')
# Find the input box
input_el = driver.find_element(By.XPATH, '//some-xpath')
msg = 'Done! 😈 💯'
paste_content(driver, input_el, msg)
You can not do it directly. You need to do this via javascript.
Once Javascript has been formatted properly, you need to notify listeners.
Before that, you need to find the unicode of any emoji you want to use.
To get codepoint of any emoji, this website can be used:
https://emojipedia.org/
Search for any emoji and at the bottom of the page, there will be the codepoint for it.
To convert codepoint to unicode for javascript, use following website:
https://r12a.github.io/app-conversion/
Type the codepoint and copy the value in javascript box of it.
Once, you have it, use JavaScript as follows:
JS_ADD_TEXT_TO_INPUT = """
var elm = arguments[0], txt = arguments[1];
elm.value += txt;
elm.dispatchEvent(new Event('change'));
"""
elem = driver.find_element_by_id('<Id of your webelement>')
text = u'\u2764'
driver.execute_script(JS_ADD_TEXT_TO_INPUT, elem, text)
2764 is unicode for heart emoji.
Hope this helps for any kind of emoticons you want to insert to your whatsapp!
Edit: For more complex emoticons:
You need to add multiple unicodes like
Emoji for family : 👪
\uD83D\uDC6A
guys.
I found a really simple but powerfull way to add emoji to whatsApp using Selenium
Message_box.send_keys(':emoji' u'\ue007') # You just have to enter the code cording to the next page
https://gist.github.com/hkan/264423ab0ee720efb55e05a0f5f90887
Copy the emoji to clipboard and paste in the input element will work too.
mch22, men your trick is awesome! thank you very much.
just in case someone is wondering how to do a line break inside the text, you can use labels within the text like this:
text = '⚪<br>📢<br>😆'
punctures perfect for my whatsapp bot!

Categories