Selenium automates browsers. It is primarily used for automating web applications for testing purposes and boring web-based administration tasks.
At the core of Selenium is WebDriver, an interface to write instruction sets that can be run interchangeably in many browsers.
Let’s install Selenium using pip: python3 -m pip install Selenium.
ChromeDriver is a separable executable that Selenium WebDriver uses to control Chrome. You need to follow there steps:
# .zshrc (Zsh's configuration file)
PATH="$PATH:~/.local/bin/chromedriver"
from selenium import webdriver
import time
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
names = ['myContact1', 'myContact2', ...]
def startup():
options = webdriver.ChromeOptions() # This is a class for managing ChromeDriver specific options.
options.add_argument("--user-data-dir=~/.config/google-chrome/Wtsp")
This is a path to your Chrome profile. Where is your Chrome profile? I am glad you ask, open your Google Chrome and type chrome://version/ into its address bar, e.g., Profile Path ~/.config/google-chrome/Default
That’s what we need so this code reads our QR code and stores it in cookies in our profile.
driver = webdriver.Chrome(options=options) # It creates an instance of the webdriver class.
driver.get('https://web.whatsapp.com/')
# It navigates to a web page, more specifically the WhatsApp webpage.
input('Enter anything after scanning QR code')
return driver
def shareWhatsApp(filepath, string):
# This method has two arguments: filepath, the image's path that we want to share, and string the text that we are going to send with the image
driver = startup()
for name in names: # We loop for all our contacts
user = driver.find_element_by_xpath('//span[@title = "{}"]'.format(name))
Open Chrome, and go to More tools, Developer Tools, Select an element in the page to inspect it, e.g., one of my contact. There are various strategies to locate elements in a page. XPath is the language used for locating nodes in an XML document and HTML is an implementation of XML.
My contact is inside a span element (//span) with a title attribute set to my contact’s name ([@title = “{}”])
<span dir="auto" title="myContact" class="ggj6brxn gfz4du6o r7fjleex g0rxnol2 lhj4utae le5p0ye3 l7jjieqr i0jNr">
myContact
</span>
user.click() # Let's click on the contact.
attachment_box = driver.find_element_by_xpath('//div[@title = "Attach"]')
Let’s find out where the Attach button is:
<div aria-disabled="false" role="button" tabindex="0" class="_26lC3" data-tab="10" title="Attach" aria-label="Attach">
<span data-testid="clip" data-icon="clip" class="">
<svg viewBox="0 0 24 24" width="24" height="24" class=""><path fill="currentColor" d="M1.816 .... 645 3.971z"></path></svg>
</span>
</div>
In other words, it is in a div (//div), and the attribute is title=“Attach”, so the XPath is //div[@title = “Attach”]
attachment_box.click() # Let's click on it.
Now, we are searching for the html button (input) to attach an image:
<button aria-label="Photos & Videos" class="_2t8DP" data-animate-menu-icons-item="true" style="opacity: 1; transform: translateY(0%) scaleX(1) scaleY(1);">
<span data-testid="attach-image" data-icon="attach-image" class="_2QbRL">
<svg viewBox="0 0 53 53" width="53" height="53" class=""><defs><circle id="image-SVGID_1_" cx="26.5" cy="26.5" r="25.5"></circle></defs><clipPath id="image-SVGID_2_"><use xlink:href="#image-SVGID_1_" overflow="visible"></use></clipPath><g clip-path="url(#image-SVGID_2_)"><path fill="#AC44CF" d="M26.5-1.1C11.9-1.1-1.1 5.6-1.1 27.6h55.2c-.1-19-13-28.7-27.6-28.7z"></path><path fill="#BF59CF" d="M53 26.5H-1.1c0 14.6 13 27.6 27.6 27.6s27.6-13 27.6-27.6H53z"></path><path fill="#AC44CF" d="M17 24.5h18v9H17z"></path></g><g fill="#F5F5F5"><path id="svg-image" d="M18...501Z"></path></g></svg>
</span>
<input accept="image/*,video/mp4,video/3gpp,video/quicktime" type="file" multiple="" style="display: none;">
</button>
We are looking for the input inside the button (//input), and the attribute is accept=“image/*,video/mp4,video/3gpp,video/quicktime”, so the XPath is: //input[@accept=“image/*,video/mp4,video/3gpp,video/quicktime”
image_box = driver.find_element_by_xpath('//input[@accept="image/*,video/mp4,video/3gpp,video/quicktime"]')
image_box.send_keys(filepath)
# We have already found the input to attach our image and use the method send_keys to attach our image (the full path is indicated in the variable filepath)
time.sleep(3)
# It is always good practice to wait for a few seconds
Finally, we are going to send the text. The input box (Type a message…) is in a div (//div) and has two attributes: class="_13NKt copyable-text selectable-text", and data-tab=“10”, so XPath = //div[@class="_13NKt copyable-text selectable-text"][@data-tab=“10”]. 1
<div title="Type a message" role="textbox" class="_13NKt copyable-text selectable-text" contenteditable="true" data-tab="10" dir="ltr" spellcheck="false" data-ms-editor="true">
</div>
inp_xpath = '//div[@class="_13NKt copyable-text selectable-text"][@data-tab="10"]'
input_box = driver.find_element_by_xpath(inp_xpath)
input_box.send_keys(string + Keys.ENTER)
# Once we have located the input box, we send the text and the Enter/Return Key.
time.sleep(10)
# It is a good practice to wait some time before we send the next message.
Finally, we can call it from our __main__; or another source Python file: shareWhatsApp(myAbsoluteUrlImage, mymessage)
WhatsApp is constantly changing or providing new features that give users some great benefits and programmers great headaches, and this code will stop working at any moment, e.g., @data-tab=“10” and you can reed in GeeksForGeeks.org, Whatsapp using Python!: inp_xpath = ‘//div[@class="_13NKt copyable-text selectable-text"][@data-tab=“9”]’ ↩︎