I cannot find a "button onclick" element using Selenium and Python - python

I am automating a process using Selenium and python. Right now, I am trying to click on a button in a webpage (sorry I cannot share the link, since it requires credential to login), but there is no way my code can find this button element. I have tried every selector (by id, css selector, xpath, etc.) and done a lot of googling, but no success.
Here is the source content from the web page:
<button onclick="javascript: switchTabs('public');" aria-selected="false" itemcount="-1" type="button" title="Public Reports" dontactassubmit="false" id="public" aria-label="" class="col-xs-12 text-left list-group-item tabbing_class active"> Public Reports </button>
I also added a sleep command before this to make sure the page is fully loaded, but it does not work.
Can anyone help how to select this onclick button?
Please let me know if you need more info.
Edit: you can take a look at this picture to get more insight (https://ibb.co/cYXWkL0). The yellow arrow indicates the button I want to click on.

The element you trying to click is inside an iframe. So, you need to switch driver into the iframe content before accessing elements inside it.
I can't give you a specific code solution since you didn't share a link to that page, even not all that HTML block. You can see solutions for similar questions here or enter link description here. More results can be found with google search

Related

Selenium - Can't click link having onclick event

So this is the link I'm trying to click:
<a class="nav-link text-light" href="#" onclick="return hydra.dissent.selectCommentsTab(event, 'top', {"url":"https://www.some-website.com/","v":"begin","uid":"5xxxxxxx5f2bc7d4b7","s":"controversial","p":1,"cpp":10});">Top</a>
I fetched it using driver.find_element(By.CSS_SELECTOR, "a.nav-link.text-light") and verified it by using get_attribute("innerText") and it did show Top.
But when I try .click() on it, nothing seems to happen.
I also tried .send_keys(Keys.ENTER) and that didn't work either.
Then I tried driver.execute_script("<onclick_text_here>"); still no luck.
The code doesn't throw any error either, so I don't know what the issue is.
Any help would be appreciated.
href="#"
basically means even if you click, it won't redirect you anywhere.
and text also says Top, may be when you click it scroll till Top which can be achieved by many ways in Selenium.

How to find the "See More Posts from..." button? Selenium - Python

Disclaimer: sorry if my explanation is weird. It's my first week learning.
As my first project, I've set out to build a program that counts Instagram posts in a given time frame. Almost everything works, but there is one button standing in my way. (sometimes)
When you open up Instagram with WebDriver, the GDPR notice pops up. This is easy to get rid of since the xpath for this button is always the same. Or less barbaric way:
driver = webdriver.Chrome()
driver.get(ig_link)
driver.find_element_by_xpath('//button[text()="Accept"]').click()
then, I want to scroll down and during it, get URLs of all posts on the page. As I've already mentioned, on some profiles this works just fine. Yet on others, only few recent posts load up and then you are required to press this pesky "Show More Posts from {instagram_tag}"
My idea was to just brute-force it through driver.find_element_by_xpath() but then I found out that on different IG pages, the xpath is different. The button also doesn't have any text directly inside it, so I am not able to use the same approach that I've used with the "Accept" button.
<button class="tCibT qq7_A z4xUb w5S7h">
<div class="Igw0E IwRSH eGOV_ _4EzTm lC6p0 HVWg4">
<div class="_7UhW9 xLCgt qyrsm h_zdq uL8Hv l4b0S ">Show More Posts from choco_afro
</div>
</div>
</button>
My idea is that I check whether the div element under button includes text "Show More Posts" and then click the button, but I don't know how to do that if even possible. Would anybody be so kind and help me with this? :)
I believe, that, this xpath might help you.
//button//div[contains(text(), 'Show More Posts')]/../..
If each IG page has the same HTML design, then this example should help you. Solution: Click Show More Posts Button
driver.find_element(By.XPATH, "//button//div[contains(text(), 'Show More Posts')]/../..").click()
Try this:
btn = driver.find_element_by_xpath('//button[#class = "tCibT qq7_A z4xUb w5S7h"]')
div = btn.find_elements_by_tag_name('div')[1]
if 'Show More Posts' in div.text.strip():
btn.click()
You can use the following to retrieve that button from it's sibling's text by css selector.
//div[text()='Show More Posts from choco_afro']/parent::div/parent::button

Selenium Click JS Button - Python?

yeah, there are similar question, but upon reading through them I weren't able to find a solution for my problem.
Following situation: I'm tryin to click the "reply" button on "https://charleston.craigslist.org/ctd/d/charleston-2018-nissan-sentra-sedan-4d/7108660907.html" and after executing this click a popups shows up where I shall click another button, but let's start with the first button as the "reply" click itself is very trouble-making.
The reply button has the following X-Path:
'/html/body/section/section/header/div[2]/div/button'
speaking of which the source code is:
<button role="button" class="reply-button js-only" data-href="/__SERVICE_ID__/chs/ctd/7108660907">
reply
</button>
(see code on mentioned website).
However, my approach with Selenium (Python) doesn't work:
reply_button = '/html/body/section/section/header/div[2]/div/button'
driver.get('https://charleston.craigslist.org/ctd/d/charleston-2018-nissan-sentra-sedan-4d/7108660907.html')
driver.find_element_by_xpath(reply_button).click()
Everytime I tried, the website just loads up properly (even with implementing time.sleep(x)) and tries to click the button, but this fails and the website just refreshes - my guess is that they either regocnize the browser being Selenium-controlled, that the click isn't legitimate or that I didn't catch anything right in my code.. Anyone able to help out?
Btw I already tried searching "by_class_name", that didn't work either.
This Xpath: '/html/body/section/section/header/div[2]/div/button' is like when you get a map with instructions like step forward until you see a car then turn left 30° then step forward until you see a tree then hop twice then go to the second house to your right. Not safe to use, avoid such paths. If the page layout changes, your path may become invalid.
Try this:
button = driver.find_element_by_xpath('//*[#class="reply-button js-only"]')
button.click()
Clicking the button opens a "show phone number" popup (which may be located by driver.find_element_by_xpath('//*[#class="show-phone"]')).
Explanation:
If you want proper Xpath, inspect what you want to interact with. The button you want to click is this:
<button role="button" class="reply-button js-only" data-href="/__SERVICE_ID__/chs/ctd/7108660907">
reply
</button>
You can see that it has no "id" tag but it is a button with a specific class. You may copy right away the "class" part -> class="reply-button js-only"
Now you can check if is it unique enough:
driver.find_elements_by_xpath('//*[#class="reply-button js-only"]')
If "find elements" returns a single result, usually you should be OK. You can see that all I did is that I pasted the class inside this: driver.find_elements_by_xpath('//*[# and this ]').
If you need more accuracy, you can specify that it is a button:
driver.find_element_by_xpath('//button[#class="reply-button js-only"]')
Or it is the direct child of the element with class: class="actions-combo", so a more safe path would be:
driver.find_element_by_xpath('//*[#class="actions-combo"]/button[#class="reply-button js-only"]')
This pattern works for all webelement attributes, not just for classes. You could use the role="button" too for more filtering. Look up for Xpath, it is a pretty neat stuff.

Selenium not finding tab link elements by various methods

I'm having issues with Selenium locating a set of specific tab link elements by IDs or link text. Using Selenium, I'm trying to click/loop through each of the tabs ("DESCRIPTION AND PRICE", "FINISH", and "NOTES") and scrape the subsequent table (see screenshot).
Below is the HTML of the tabs. When my loop first loads the page, the "DESCRIPTION AND PRICE" tab is active, and the subsequent table is easily scraped with BeautifulSoup (by searching for the with the specific table ID). However, after the "D+P" table is scraped, I try to click the "FINISH" tab with Selenium, I get the NoSucElementException error.
I hope to be able to click on the "FINISH" and "NOTES" tabs using the link text method (since the tabs are different from page to page). This results in the error.
driver.find_element_by_link_text("FINISH").click()
I've also tried the ID method, but this fails too.
driver.find_element_by_id("cphMain_tbTabs_rptTabs_lnkTab_1").click()
I've also tried various wait methods in case the element just wasn't yet loaded, although I get the same error when attempting to wait for an element ID, because it can't find the ID.
Another consideration is that I'm not seeing any mention of an iframe in the html.
<div id="cphMain_upTabs">
<div id="cphMain_divTabs" class="tabs">
<div id="cphMain_tbTabs_divTabs">
<ul class="tabset">
<li><a id="cphMain_tbTabs_rptTabs_lnkTab_0" class="tab active" href="javascript:__doPostBack('ctl00$cphMain$tbTabs$rptTabs$ctl01$lnkTab','')" style="font-weight:bold;">DESCRIPTION AND PRICE</a></li>
<li><a id="cphMain_tbTabs_rptTabs_lnkTab_1" class="tab" href="javascript:__doPostBack('ctl00$cphMain$tbTabs$rptTabs$ctl02$lnkTab','')" style="font-weight:normal;">FINISH</a></li>
<li><a id="cphMain_tbTabs_rptTabs_lnkTab_2" class="tab" href="javascript:__doPostBack('ctl00$cphMain$tbTabs$rptTabs$ctl04$lnkTab','')" style="font-weight:normal;">NOTES</a></li>
</ul>
Looks like my issue was with the first page I'm checking - I've added Try/Except logic and now I'm able to skip the first page and scrape the info for the subsequent pages. Not sure what the issue is with the first page...

Selenium cannot find element in chromedriver

I am trying to automate some actions on a website. My script fills out a form and clicks post and then the website essentially asks if you are sure you want to post and you need to click the post button a second time. The problem is, while the old post button is no longer visible to the user, Selenium can only find the old post button and insists that the new post button does not exist.
Here is what the HTML looks like for the new post button.
<span id="__w2__w927tml1_submit_question_anon">
<a class="modal_cancel modal action" href="#"
id="__w2__w927tml1_add_original">Ask Original Question</a>
</span>
I have tried every different locator I can think of but it always locates the old post button. The closest I've got is locating the parent class shown above, but when trying to parse through its children it says there are none. I am at a loss for what to do here. Thanks for your help.

Categories

Resources