I am trying to create a workaround to click the first element in a table on a website that has an overlay table. The xpath does not appear to be related to the iframe, but I do not HTML.
The text does not link anywhere, but when clicked, it goes away and I can continue using the webpage.
The for loop goes through and searches vin numbers and gets prices, but some vins, for some odd reason are shared by the same vehicle with different trims. I am not comfortable sharing the table, but to describe it visually, it grays out the background, similar to a cookie alert and has entries representing the different clickable trims.
The code for detail.
for j in range(0,len(vins)):
try:
normal loop
except:
driver.find_element(By.XPATH, '/html/body/div[2]/div/div/div[2]/div/div/div[2]/div[1]/div/div/div/div/div[2]/div/div/div/div[3]/table/tbody/tr[1]/td[1]').click()
Error from query is InvalidArgumentException: invalid argument: invalid locator
Related
I am working on this website
Basically I want to capture 2 latest news from News section that is below the table and store that news in some json and collect picture if possible but I am not able to go to the news section as It always raise error saying
selenium.common.exceptions.ElementClickInterceptedException: Message: Element <a id="ctl00_ContentPlaceHolder1_CompanyDetail1_lnkNewsTab" href="#divNews"> is not clickable at point (307,786) because another element <iframe id="webpush-onsite" name="webpush-onsite"> obscures it
here is some part of code I tried tough
driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
stocks_data = ["AKPL","NICA"]
for stock_data in stocks_data:
self.driver.get(f'https://merolagani.com/CompanyDetail.aspx?symbol=
{stock_data.lower()}')
self.driver.find_element_by_xpath("//li[#id='navNews']"
"//a[#id='ctl00_ContentPlaceHolder1_CompanyDetail1_lnkNewsTab']").click()
If you really need to click it regardless a normal user won't be able because as the error says, there's an IFrame on top of it...
Try the following:
Set the window size to 1920x1080 or so, maybe the elements overlap because the screen on Selenium's session is too small 🤷♂️
Worst case scenario, inject some Javascript code to do it forcefully:
self.driver.execute_script("document.getElementById('ctl00_ContentPlaceHolder1_CompanyDetail1_lnkNewsTab').click()")
Click on exact coordinate (x,y) if you know it ofcs.
am new to coding and have been trying to select a dropdown box to select underlying options. Have been able to interact with other drop-down on this page, though this particular one seems different as I've been unable to access/interact with it
I've included a snapshot of the webpage's drop-down box, source codes for the specific drop-down box, and codes that I've already tried and had errors with.
Would appreciate any help/pointers. Am a complete newb to coding (python or HTML!), but know a little about Excel VBA.
website: https://www.firstsentierinvestors.com/sg/en/retail/performance/price-and-performance.html
Tried to paste a picture though it seems I'm too new to do so directly. I'm trying to interact with the "Select Fund" drop-down box on the page. Have tried the following codes:
browser.find_element_by_id('strategy').send_keys(fund_strat) #works fine
browser.find_element_by_xpath('//*[#id="share-class"]').click()
#this line directly above does not work, including variants below:
browser.find_element_by_xpath('THE BELOW XPATHS').click()
//*[#id="price-performance-form"]/div[3]
//*[#id="price-performance-form"]/div[3]/div
//*[#id="price-performance-form"]/div[3]/div/a
//*[#id="price-performance-form"]/div[3]/div/a/span
//*[#id="share-class"]
//*[#id="share-class"]/option[1]
Also tried using CSS selector
browser.find_element_by_css_selector('a.option-selected').click()
browser.find_element_by_css_selector('a.option-selected').send_keys('NAME OF FUNDS ETC')
Image describing problem
If the below line works fine for you then,
browser.find_element_by_xpath('//*[#id="share-class"]').click()
#this line directly above does not work, including variants below:
You need to wait for the element which is visible on the DOM.
i.e.,css = <div class="custom-select custom-select-open">
These days most of the web apps are using AJAX techniques.
So you need to add a wait duration (till the element gets visible on the page or get loaded on the DOM).
So, Try using Selenium Waits(put below code):
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.XX, 'element')))
XX = CSS, XPATH, ID, etc.
Now, If you want to write on the selected text box then just try to send keys on input element.
browser.find_element_by_css_selector('.editable-select input')
for much better selector use parent elements to locate the exact element.
CSS = 'div[class$="custom-select custom-select-open"] .editable-select input'
If you want to select dropdown options and you know the Values. Try using below CSS.
browser.find_element_by_css_selector('select option[value$="Your Value"]')
or
If you don't know the values then please attach whole DOM feed after typing into the text box. I'll try to help you out with the Dropdown selection of item.
Else, there is few more steps are there that you need to workout. Get all elements using inside text.
Note: You can approach the text search of an element using XPATH. Example : xpath = "//*[contains(text(),'your text')]"
I am having trouble finding elements on a customer-facing webpage that I am scraping data from, using Robot Framework + Selenium. My trouble, I think, has to do with the desired data existing in a popup/frame. The data I seek is located on a customer's invoice, which pops up when I press a button ("View Current Invoice"). I've been successful with logging into the site and navigating around, and at one point I was successful pressing the View Current Invoice button to cause the invoice to pop up - but forgot to commit that code and lost it. :-(
In any case, eve if I manually enter the popped up invoice by pressing the button when my script is expecting it to be pressed, I can't seem to scrape the subsequent data. I have tried to identify elements on the invoice using locators (from Right-Click-Inspect capability built into Firefox and Chrome; Katalaon Recorder; Selenium IDE; etc.). I get what looks like a valid locator (almost always Xpath); yet when I run my Robot script, it fails to find the element in question. I have spent a lot of time poring over the page's source code, but since I am not as savvy with HTML/JS/CSS as I should be, I haven't been successful.
Here is a screenshot of the invoice button:
And here is what I see when the button is pressed. I want to scrape all the invoice data, like Amount Due, Invoice Number, Due Date, etc.
Does anyone have any idea what I am missing here? What would you do to get the data on the invoice if you were in my shoes? I know my question probably sounds vague and naiive, but I am at the end of my rope, so to speak. I am willing to share page source code, more screenshots, whatever is required.
EDIT I used Rahul Rai's method to inspect the popup while it was popped up; then searched for "iframe". There were 10 matches; #7, when clicked on, resulted in the invoice popup being highlighted in blue:
I assume this means this is the iframe referencing the popup? If so, I should be able to find information about the "handle" to the iframe in the inspection code, but I don't see anything there that matches the locators I am used to (e.g. name, id, xpath). I even tried "Select Frame 1599252503952", but that just resulted in a
"Element with locator '1599252503952' not found" error.
As per above screen you have shared I can see your Invoice details are inside iframe. So after clicking on View Current Invoice button you can use below code to navigate inside frame and then scrape required information.
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[contains(#src,'invoice_detail_container']")))
#Code to scrape data
ele = driver.find_element_by_xpath('<xpath>')
print(ele.txt)
......
......
#After your work is done in this frame to navigate back to main window
driver.switch_to.default_content()
Note: I have assumed your main frame for invoice is not in side any other iframe ( Based on screen shared). Also before elements start there is no other nested frame. If there is any other nested frame you need to navigate first into that.
I was finally able to scrape data from the Invoice popup after inspecting the HTML source, and seeing this:
<iframe frameborder="0" src="/cmc/invoice_detail_container.pyt?direction=//my.hughesnet.com/cmc/invoice_detail.pyt%3Finvnumber%1234-567890&portletId=863" name="1599391562960" class="cboxIframe" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true"></iframe>
I was then able to use the Select Frame keyword in Robot Framework, specifying the iframe locator for the popup, using the 'class' strategy. I also had to explicitly select the main body frame first. In the end, the code that allowed me to enter the iframe and scrape was:
Select Frame body
Select Frame class:cboxIframe
Big thank you to Rahul Rai for pushing me closer to the solution; and thanks to the others who answered as well.
You need to switch your site to frame/popup, you can use like below example, may be it will help you.
IList<IWebElement> textfields = new List<IWebElement>();
textfields = driver.FindElements(By.TagName("iframe"));
driver.SwitchTo().Frame(textfields[count); // number of textfields list.
please try to implement as per your scenario, let me know if any question.
You can try to do :
driver.switch_to_active_element()
and then scrape the popup to close it. Then I think it will be okay...
Trying to click on the button on "https://euw.op.gg/summoner/userName=JengaSneaky". But I can't find the element that trigger it.
The pic shows one of the buttons. I want Selenium to click on it so I can scrape the data that pops up. I've tried to find the element but it says I can't use it with click().
The problem with these kind of buttons is that they are generated each time you load the html ( or the page ) based on the data contained in a database that changes everyday.
That's why they don't come with a unique id or something to distinguish them from others.
The thing you could do here is to find them by the CSS SELECTOR or by XPATH.
But you will always have to check if they changed everyday.
What you could also try to do is locate them if they contain a specific text.
I am attempting to scrape the Census website for ACS data. I have scripted the whole processes using Selenium except the very last click. I am using Python. I need to click a download button that is in a window that pops when the data is zipped and ready, but I can't seem to identify this button. It also seems that the button might change names based on when it was last run, for example, yui-gen2, yui-gen3, etc so I am thinking I might need to account for this someone. Although I normally only see yui-gen2.
Also, the tag seems to be in a "span" which might be adding to my difficulty honing in on the button I need to click.
Please help if you can shed any light on this for me.
code snippet:
#Refine search results to get tables
driver.find_element_by_id("prodautocomplete").send_keys("S0101")
time.sleep(2)
driver.find_element_by_id("prodsubmit").click()
driver.implicitly_wait(100)
time.sleep(2)
driver.find_element_by_id("check_all_btn_above").click()
driver.implicitly_wait(100)
time.sleep(2)
driver.find_element_by_id("dnld_btn_above").click()
driver.implicitly_wait(100)
driver.find_element_by_id("yui-gen0-button").click()
time.sleep(10)
driver.implicitly_wait(100)
driver.find_element_by_id("yui-gen2-button").click()
enter image description here
enter image description here
Instead of using the element id, which as you pointed out varies, you can use XPath as Nogoseke mentioned or CSS Selector. Be careful to not make the XPath/selector too specific or reliant on changing values, in this case the element id. Rather than using the id in XPath, try expressing the XPath in terms of the DOM structure (tags):
//*/div/div/div/span/span/span/button[contains(text(),'Download')]
TIL you can validate your XPath by using the search function, rather than by running it in Selenium. I right-clicked the webpage, "inspect element", ctrl+f, and typed in the above XPath to validate that it is the Download button.
For posterity, if the above XPath is too specific, i.e. it is reliant on too many levels of the DOM structure, you can do something shorter, like
//*button[contains(text(),'Download')]
although, this may not be specific enough and may require an additional field, since there may be multiple buttons on the page with the 'Download' text.
Given the HTML you provided, you should be able to use
driver.find_element_by_id("yui-gen2-button")
I know you said you tried it but you didn't say if it works at all or what error message you are getting. If that never works, you likely have an IFRAME that you need to switch to.
If it works sometimes but not consistently due to changing ID, you can use something like
driver.find_element_by_xpath("//button[.='Download']")
On the code inspection view on Chrome you can right click on the item you want to find and copy the xpath. You can they find your element by xpath on Selenium.