I'm trying to get the first two divs of a given class from a web site using css selectors in selenium. I'll use SO to demonstrate the problem. If I try the selector in the console chrome dev tools it works:
$('div.question-summary:eq(0)')
[<div class="question-summary narrow tagged-interesting" id="question-summary-27442616">…</div>]
$('div.question-summary:eq(1)')
[<div class="question-summary narrow tagged-interesting" id="question-summary-27442177">…</div>]
But if I do the following with selenlium webdriver I get an error:
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome
driver.navigate.to('http://www.stackoverflow.com')
first_element = driver.find_element(:css, 'div.mainnav:eq(0)')
Selenium::WebDriver::Error::InvalidSelectorError: invalid selector: An invalid or illegal selector was specified
Is there another way to express this selector? Or a way to get selenium to respond to it?
Selenium uses the browser's native CSS selector engine. As a result, the find_element method will consider jQuery selectors, in this case the :eq(0), as being invalid.
If you want to use jQuery selectors, you will need to manually execute that script using the execute_script method. Note that when using this approach an array of Selenium::WebDriver::Element will be returned, which is why the .first is used (to get the first element of the Array).
first_element = driver.execute_script('return $("div.question-summary:eq(0)");').first
That said, if the only jQuery selector you are trying to use is :eq, you could get by with standard CSS selectors. The :eq selector returns a specific element within the matching set. You could do the same by using the find_elements and [] methods:
first_element = driver.find_elements(:css, 'div.question-summary')[0]
second_element = driver.find_elements(:css, 'div.question-summary')[1]
You can get a similar result with :nth-child:
first_element = driver.find_element(:css, 'div.question-summary:nth-child(0)')
Just be aware of the difference between :eq and :nth-child
Related
So I start my scrapy shell with
scrapy shell 'https://www.amazon.com/s?k=tomatoes&ref=nb_sb_noss_1'
And I am trying to scrape the title of the products so I enter
response.xpath('//span[#class="a-size-base-plus a-color-base a-text-normal"]').getall()
and get: []
And when I tried it in CSS with
response.css("span.a-size-base-plus a-color-base a-text-normal").getall()
I still get: []
I don't understand why it isn't finding the element even though I am copying and pasting the tags and classes from the site.
I have also tried just writing a-size-base-plus for the classes in XPath and CSS but I still get nothing
You need to replace the spaces between the classes with dots if you want to match multiple classes on elements:
response.css("span.a-size-base-plus.a-color-base.a-text-normal").getall()
instead of:
response.css("span.a-size-base-plus a-color-base a-text-normal").getall()
Your selector with spaces says something like: Give me all a-text-normal elements inside a-color-base elements inside span elements with a class of a-size-base-plus. This is of course not what you want.
I've also had to set a user agent to get the correct results. See this answer on how to set the user agent using scrapy shell.
How to handle elements which does not have unique accessibility id's
Please find the below link for screenshot
First, you should avoid using XPath with Appium on iOS: it's not natively supported by XCUTest and because of it, significantly affects performance of elements search.
Second, it would be nice to set accessibility label even it will be a group of elements with the same one:
Here is a Java sample how you can search and select one of the elements with same id:
List<WebElement> elsWithSameId = driver.findElements(MobileBy.AccessibilityId("your id"));
WebElement specificElement = elsWithSameId.stream()
.filter(element -> element.getText() == "My Favorite element")
.findFirst()
.get();
specificElement.click();
If you still want to use XPath, just try to find more/less unique class for the elements you want to interact with, then build iOS predicates (similar mechanism to XPath, but its native to XCUITest)
hi how to use Get Element Attribute in Robot framework? in instruction I have
Return value of element attribute.
attribute_locator consists of element locator followed by an # sign and attribute name, for example element_id#class.
I have this xpath=${check_radio_xpath}#class is this right way?
where ${check_radio_xpath} = md-radio-11
I get this error:
${ischecked} = Selenium2Library . Get Element Attribute xpath=${check_radio_xpath}#class
Documentation:
Return value of element attribute.
TRACE Arguments: [ 'xpath=md-radio-11#class' ]
DEBUG Finished Request
FAIL ValueError: Element 'xpath=md-radio-11' not found.
I think you're pretty close. Please try to format your question better, I took a quick shot because your question is difficult to read. The result will be more and better help from the community
${RADIO_XPATH} //*[#id="${check_radio_xpath}"]
${CLASS}= Selenium2Library.Get Element Attribute ${check_radio_xpath}#class
sample for this <div><label for="foo"></label></div>
${for_value}= Get Element Attribute xpath=//div/label for
Log To Console ${for_value}
console result is:
foo
This snippet works for me :
Get Line Numbers And Verify
${line_number1}= Get Element Attribute //*[#id="file-keywords-txt-L1"] data-line-number
Log To Console ${line_number1}
${line_number2}= Get Element Attribute //*[#id="file-keywords-txt-L2"] data-line-number
Log To Console ${line_number2}
Verify in order of ${line_number1} and ${line_number2} is true
What was important is that the spaces/tabs between the keywords are correct, otherwise it does not get recognised as a so called keyword.
Thanks a lot, i wanted to check meta noindex content in page source.
i used this.
${content} Get Element Attribute xpath=//meta[#name="robots"]#content
should be equal as strings ${content} noindex,follow
You can use both XPath and CSS selector if you have selenium library
${title}= Get Element Attribute ${xpath} attribute=title
The CSS selector [attr|=value] is designed to select items which are exactly "value" or which begin with "value-". This was originally intended to allow selection of all languages regardless of dialect, such as "en-au", "en-ca", "en-gb", "en-us".
What I'm looking for is a selector for an item which is exactly "value", which includes "-value-" or which ends with "-value". In my case, I am not concerned with language codes at all.
This page claims that there is a =\operator:
[data-value=|"foo"] {
/* Attribute value has this in a dash-separated list somewhere */
}
However I have been unable to get this to work. If I'm just interested in a controlled list of 2-item terms, then this will work for me:
[attr*=-value][attr$=value]
However, this would also return items like "xx-valuevalue", so the result is not perfect.
My question is: is there another way to write a CSS selector that will select all items that have a given string as one item in a hyphen-delimited list?
Here you go:
[attr*=-value-], [attr$=-value], [attr=value]
In pseudo code:
Get those containing -value-, those ending with -value, and those exactly equal to value.
I am using selenium 2 (WebDriver).
I am locating a button and clicking by the script:
driver.findElement(By.cssSelector("button:contains('Run Query')"));
or
driver.findElement(By.cssSelector("css=.gwt-Button:contains('Run Query')"))
whose html is like :
<button type="button" class="gwt-Button" id="ext-gen362">Run Query</
button>
As the id is dynamically generated, I can't make use of the ID.
Is there any way to use cssSelector with something like contains ? Is this possible?
You can't do this with CSS selectors, because there is no such thing as :contains() in CSS. It was a proposal that was abandoned years ago.
If you want to select by the element text, you'll have use an XPath selector. Something like
driver.findelement(By.xpath("//button[contains(., 'Run Query']"))
or
driver.findelement(By.xpath("//[contains(concat(' ', #class, ' '), ' .gwt-Button ') and contains(., 'Run Query']"))
Another option is using jQuery, if it's present on the page, something like:
var webElement = ((JavascriptExecutor)driver).executeScript("return jQuery('button:contains(Run Query)')");
CSS alone will not get you what you need; you cannot filter by the text. You could either use js to get the id of the element, or loop through all the buttons in your code until you find the one with the right text. If this were in python:
[btn for btn in browser.find_elements_by_css_selector('button')
if 'Run Query' in btn.text]
You could easily generalize this and make a helper function, too.
I'm in the same boat, currently using XPath selectors with "contains" to find elements with specific text content. Some are <td> and some are <td><a> deep within large tables (specific columns, but row unknown in advance). It's very slow (4 to 5 seconds just to find such a table entry with Firefox 20), so I was hoping to use CSS to be faster. Often the text will be by itself (complete) and other times it will be a filename at the end of a path I'd like to ignore. Does anyone have suggestions for the fastest XPath search pattern, given that it's a known column but unknown row, and may be a <td> or <td><a> (sometimes in the same table). Would an equality comparison be much faster than contains(), for the majority of cases where the text I'm looking for is complete (not at the end of other text)? I think there's a "starts with" lookup, but is there an "ends with" lookup? I know that using an "id" would be even faster, but unfortunately this HTML doesn't have any IDs here, and they can't be added. I'm looking to find the <tr> containing this text so I can locate another element in the same row and get its text or click on a link. It doesn't hurt to locate a small subset of the rows and check their text, but I'd like to avoid doing separate searches for <td> and <td><a> if that's possible.
You cannot use contains but use a wild card instead.
driver.findElement(By.cssSelector("button:(*'Run Query'*)"));
driver.findElement("#ext-gen362").Where(webElement => webElement.Text.Contains("Run Query"))