Opening more than two tabs with selenium - python

I'm currently using chrome(selenium) to automate something for me. For some reason I cannot get selenium to open up another webpage.
def gotoInventory():
#WebDriverWait(driver,5)
inventoryPS = driver.switch_to.window(driver.window_handles[1])
inventoryPS
openInventoryTab = driver.execute_script("window.open('https://sellercentral.amazon.com/inventoryplanning/dashboard','new window')")
openInventoryTab
def loginProton():
#Need to create a new tab to open proton mail
ActionChains(driver).key_down(Keys.CONTROL).send_keys('t').key_up(Keys.CONTROL).perform()
#above code did not work
#also tried browser.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
openProtonTab = driver.execute_script("window.open('https://mail.protonmail.com/login','new window')")
openProtonTab
For some reason selenium always opens the webpage on the inventory tab which is not what I want. protonMail has to be opened on its own tab and not on the inventory tab.
Any help would be greatly apperciated

The issue happens due to using the same window name in both cases which is 'new window'. You may try using different window names in inventory and proton cases. Also note that window.open creates a browser window.

Related

Selenium drag and drop for Avery Design & Print (Python)

I'm creating a python script to automate labels through "Avery Design & Print Online", using the 18160 template and importing a ".csv" file for the mail merge.
https://www.avery.com/templates/18160
Starting from the URL above, the script can
Login
Select the "blank" horizontal design
Click "Data Mail Merge"
Ask user for their ".csv" data file
Modify the selected ".csv" file to match the requirements for Avery Design & Print
IMPORT the newly generated ".csv" to perform mail merge.
Create a text box containing "Last Name, First Name" and "DOB" (Date of Birth)
Create a text box containing "Samples" and "Client Site"
Resize the text boxes
Open the QR codes prompt to add a barcode
Go through prompts to bring up the window where I can add the "Samples" column as the barcode data by dragging and dropping.
The issue that I'm having is that I am unable to use the "drag and drop" command in Selenium to properly drag and drop my selection ("Samples") into the required input field.
When running the script, I get no errors from the drag and drop command but it doesn't do anything on the webpage. Instead, script times out when trying to click the "Finish" button, because that element will become unclickable when the drag and drop doesn't properly place the draggable field into the droppable input field. However, the drag and drop command IS working on lines in my script that resize the text boxes (which is done outside of any prompt windows).
The "Samples" element is draggable, but using the drag and drop command does nothing.
Here are the web elements for the drag and drop
So far, I've tried:
Using javascript to perform the drag and drop. (w/CSS selectors to find element)
Using CSS selectors to find element
Use "send_keys" on the input to type 'Samples', but this just makes the barcode equal to "SAMPLES" instead of each actual sample number.
Using a series of commands instead of just "drag and drop"
Using different parts of the draggable and droppable elements to find them
I've also considered iframe issues, but the web elements are not under any iframes.
Webdriverwait for explicit wait
"time.sleep" command for implicit wait
"seletools" package (https://pypi.org/project/seletools/)
Selenium IDE to see if it generates anything different from my code. (It did not. It recorded my action as a drag and drop command. When running the code from Selenium IDE, it produces the same issue.)
Here is the snippet from my script that is failing.
InputBox = driver.find_element(By.CSS_SELECTOR, '#barcode-code-128 > div:nth-child(2) > input')
DragField = driver.find_element(By.CSS_SELECTOR, '#modal-view-ex-container > div > div > div.dpo8-add-barcode > '
'div.merge-part > div.mail-merge-part > div.dpo8-mail-merge-list > '
'div:nth-child(1) > div')
time.sleep(5)
action.drag_and_drop(DragField, InputBox)
DispTextCheckbox = WebDriverWait(driver, 5).until(
ec.presence_of_element_located((By.XPATH, '//*[#id="show-text-code-128"]'))
)
DispTextCheckbox.click()
GrNextButton2 = WebDriverWait(driver, 5).until(
ec.element_to_be_clickable((By.XPATH, '//*[#id="modal-view-ex-container"]/div/div/div[3]/div/button[3]'))
)
GrNextButton2.click()
This is after the script times out.
This is the timeout error I'm seeing:
Traceback (most recent call last):
File "PATH\test.py", line 257, in <module>
GrNextButton2 = WebDriverWait(driver, 5).until(
File "PATH\wait.py", line 89, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Process finished with exit code 1
Last thing, I will note that this seems to be an issue with this specific website/prompt. I've seen a lot of workarounds for a drag and drop bug in Selenium but none of them have changed anything and I am running into the same exact issue. I don't know if anyone might have a better understanding of what could be going on considering that this seems to be specific to this website, but I am new to scripting so maybe I'm missing something.
The web elements ARE being FOUND, but the command does nothing. The command IS running properly, but nothing is happening on the webpage. The drag and drop DOES seem to work OUTSIDE of any prompted windows on the webpage. Ultimately, I think the issue is the "prompt" window on the webpage, but I can't figure out how to get Selenium to work with it for drag and drop.
If anyone wants to help test, let me know if you need anything from me. Thanks in advance.
TL;DR - "Avery Design & Print Online" will not allow me to drag and drop "Samples" into the input field when using Selenium.

How to scrape a map on a website for informations stored in popups?

I'm relatively new to web scraping so I'm not sure about which approach I should use to collect informations in a specific scenario in which the informations are stored on a map and displayed in popups, such as : https://utils.ocim.fr/cartocim2/
Basically :
the website shows a map,
contact informations are displayed in popups,
a popup will appear when clicking on a geo-tag button,
targeted informations are those lines stored in that popup
I was thinking of using selenium + xpath method but I'm unsure regarding the way to deal :
with this amount of buttons that have to be clicked on
with the popups.
Would you have any resources / tips to advise me to know where to start ?
With great difficulty
Here's a start but it gets a little more complicated as the markers start overlapping so clicking the elements fails, might need to add a step to zoom in etc
from selenium import webdriver
import requests
import pandas as pd
url_base = r'https://utils.ocim.fr/cartocim2/'
driver = webdriver.Chrome(r'C:\Users\username\Downloads\chromedriver_win32\chromedriver.exe')
driver.get(url_base) #open page
#find all the icons
links = driver.find_elements_by_css_selector('div.leaflet-pane.leaflet-marker-pane > img')
import time
output = [] #temp table to append into
for i in range(5): #chaneg to len(links) when done
links[i].click() #click on first icon
output.append(driver.find_elements_by_xpath('//*[#id="popup-header"]')[0].text) #get the text of the name
time.sleep(1) #sleep
driver.find_element_by_css_selector('#initmap').click() #reset the map - needed as without it the next icon might not be on the screen due to map relocation or popup overlap
time.sleep(1)

use pywhatkkit in same tab instead of using new

I want to use pywhatkit to search in same tab instead of opening in new tab.I am using following code:
import pywhatkit as kit
kit.search(query)
It open new search query in new tab instead of using current tab. if anyone knows a way to handle this problem please help.
Creator/Author of the pywhatkit here, the library uses webbrowser module to search on Google and at this moment, for searching in the same tab you have to manually update the source code of the library.
To do so, go to Lib\site-packages\pywhatkit\mainfunctions.py and replace line number 230 with web.open(link,new=2), setting new=2 opens the url in same tab. I haven't tested this so I can't assure you that this will work so better to try it by importing the webbrowser module first and doing the same then update the source code.
One workaround that I found was to alter the code from the library, and I didn't actually called the library function.
import time
import webbrowser as web
import pyautogui as pg
import keyboard as kb
# Open the tab and wait for it to load
web.open(f"https://web.whatsapp.com/")
time.sleep(10)
message = 'Line 1%0aLine 2'
phone_number = '+5563999999999'
# Click on Chrome address bar then wait 1 second and click again to edit
# To find coordinates you can run
# >>> import mouseinfo
# >>> mouseinfo.MouseInfoWindow()
pg.click(1123,62)
time.sleep(1)
pg.click(1123,62)
# Type in the message, press enter, then wait page to load (8 sec) and click
# enter again to send the message
# These times will depend on internet and computer
kb.write('/send?phone=' + str(phone_number) + '&text=' + str(message_alt))
pg.press('enter')
time.sleep(8)
pg.press('enter')
# This last pause is to run this in a loop
time.sleep(2)

How to "open in a new tab" with selenium and python?

I'm writing a bot with Python/Selenium.
In my process, I want :
to right click on a picture
open it in a new chrome tab
I tried the following :
def OpenInNewTab(self):
content = self.browser.find_element_by_class_name('ABCD')
action = ActionChains(self.browser)
action.move_to_element(content).perform();
action.context_click().perform()
action.send_keys(Keys.DOWN).perform()
action.send_keys(Keys.ENTER).perform()
However, the problem is that my bot :
open the contextual menu
scroll down on the page and not on the contextual menu
After a lot of researches, I tried with :
import win32com.client as comclt
wsh = comclt.Dispatch("WScript.Shell")
wsh.SendKeys("{DOWN}")
wsh.SendKeys("{ENTER}")
However, it's not really working.
I saw many other topics, like this one (supposing there is href associated to the pic)
Then, i'm a little lost to be able to do tthis simple thing : open a righ click on contextual an element and select open in a new tab. I'm open to any advice / new road to follow.
In my experience it will be difficult to achieve a perfect "one fits all" solution involving the (context menu - new tab) combination, and I tend to keep clear of all the headache it can bring.
My strategy would be a bit different, and, on a case by case basis, I'd use something like:
base_window = driver.current_window_handle # this goes after you called driver.get(<url here>)
my_element=driver.find_element_by_xpath(...) #or whatever identification method
my_element.send_keys(Keys.CONTROL + Keys.ENTER)
driver.switch_to.window(driver.window_handles[1]) #switch to newly opened tab
driver.switch_to.window(base_window) # switch back to the initial tab
An alternative workaround is using hrefs - first open a new tab, then load the fetched href(s). Here's an example:
url='https://www.instagram.com/explore/tags/cars/?hl=en'
driver.get(url)
base_window = driver.current_window_handle
a_tags=driver.find_elements_by_xpath("//div[#class='v1Nh3 kIKUG _bz0w']//a")
hrefs=[a_tag.get_attribute('href') for a_tag in a_tags] #list of hrefs
driver.execute_script("window.open();") #open new tab
driver.switch_to.window(driver.window_handles[1]) #switch to new tab
driver.get(hrefs[0]) #get first href for example
driver.close() #close new tab
driver.switch_to.window(base_window) #back to initial tab

Python Selenium: click() cannot trigger event

I try to use selenium to mimic my action on a website to convert PDF files to EXCEL files. There are three steps to complete the conversion:
Upload the PDF file.
Input email address.
Click the 'convert' button.
I wrote the code as below. However, every time I click the button the page just refreshes without actually converting the file.
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("https://pdftoexcelonline.com/en/")
# Upload file
el_upload = driver.find_element_by_name("file")
el_upload.send_keys("/path/to/the/file")
# Input email
el_email = driver.find_element_by_name("email")
el_email.clear()
el_email.send_keys("<email address>")
# Convert button
el_button = driver.find_element_by_id("convert_now")
el_button.click()
time.sleep(10)
driver.close()
This page works well when I completed the steps manually. What is reason that my code did not trigger the conversion?
One possible reason is the not enough execution time. You can add some sleep after each action to verify. Treat it as workaround if work.

Categories