5

Each of the "7-pack" search results here contains a number of reviews e.g. "5 reviews", No reviews" etc.

The class name for each is fl r-iNTHbQvDybDU. It contains a space, so if I try find_elements_by_class_name(), I get:

InvalidSelectorError: Compound class names not permitted

According to other answers on here, all I needed to do was remove the space and retry. No luck - an empty list

So I try find_element_by_css_selector():

find_elements_by_css_selector(".fl.r-iNTHbQvDybDU")

Still no luck - empty list. What would you try next?

Pyderman
  • 14,809
  • 13
  • 61
  • 106
  • The string after **r-** looks like randomly generated to ensure uniqueness. I think that's why you cannot get anything. – Leo Mar 12 '16 at 01:06
  • Maybe this also helps: https://stackoverflow.com/questions/7475449/webdriver-classname-with-space-using-java – Nabres BR Dec 10 '21 at 13:16

4 Answers4

5

How about this:

browser.find_elements_by_css_selector("div[class='fl r-iNTHbQvDybDU']")

This assumes tag for the class = div.

If it is something else - otherwise replace div w/ the appropriate tag..

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Moe Khan
  • 51
  • 1
  • 3
1

Try this:

find_elements_by_css_selector(".r-iNTHbQvDybDU")
Eduardo Luz
  • 71
  • 1
  • 9
1

I would not rely on the auto-generated class names like these. Aside from being non-reliable, it is making your code less readable. Instead, get the links containing "review" text.

Combined solution with the Webdriver/Selenium: How to find element when it has no class name, id, or css selecector? thread:

import re

from selenium.common.exceptions import NoSuchElementException    
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver


driver = webdriver.Chrome()
driver.get('https://www.google.com/?gws_rd=ssl#q=plumbers%2BAvondale%2BAZ')

# waiting for results to load
wait = WebDriverWait(driver, 10)
box = wait.until(EC.visibility_of_element_located((By.ID, "lclbox")))

phone_re = re.compile(r"\(\d{3}\) \d{3}-\d{4}")

for result in box.find_elements_by_class_name("intrlu"):
    for span in result.find_elements_by_tag_name("span"):
        if phone_re.search(span.text):
            parent = span.find_element_by_xpath("../..")
            print parent.text
            break

    try:
        reviews = result.find_element_by_partial_link_text("review").text
    except NoSuchElementException:
        reviews = "0 Google reviews"

    print reviews
    print "-----"

Prints:

360 N Central Ave
Avondale, AZ
(623) 455-6605
1 Google review
-----
Avondale, AZ
(623) 329-5170
4 Google reviews
-----
Tolleson, AZ
(623) 207-1995
7 Google reviews
-----
3947 N 146th Dr
Goodyear, AZ
(602) 446-6576
1 Google review
-----
564 W Western Ave
Goodyear, AZ
(623) 455-6605
0 Google reviews
-----
14190 W Van Buren St
Goodyear, AZ
(623) 932-5300
0 Google reviews
-----
Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Thanks, but this also returns an empty list. If I shorten the partial text to just "reviews", still an empty list. The element is a ** - does *find_elements_by_partial_link_text()* only work for **? – Pyderman Jun 26 '15 at 04:25
  • @Pyderman updated, you just need to explicitly wait for the results to load. – alecxe Jun 26 '15 at 04:30
  • @alexce Thanks - this has been working well, in most cases. But when a search returns some results that don't have any reviews (see https://www.google.com/?gws_rd=ssl#q=plumbers%2BAvondale%2BAZ for an example), it breaks down, as it only extracts those that have a "* Google reviews" element – Pyderman Jun 27 '15 at 04:53
  • @alexce So in the cases where a result has no reviews, there is no span of style *white-space:nowrap* for that div of class "intrlu". How would we apply your approach given in this answer http://stackoverflow.com/a/31076043/1389110 here? i.e. how can we extract (i) those spans (when they are present) and (ii) somehow apply a value of "0 reviews" where the span is not present for a given result? – Pyderman Jun 27 '15 at 05:13
  • 1
    @Pyderman I would search for the `review` partial link text inside each result and catch the `NoSuchElementException` which would mean we've got 0 reviews. I've updated the code in this answer. Also, fixed the problem with a single google review (searching for `review` instead of `reviews`). Thanks. – alecxe Jun 27 '15 at 14:08
  • Belated thanks, @alecxe, this has been working nicely. – Pyderman Jul 14 '15 at 07:30
1

U need to add the tag name in front of it.

For Example, it is inside a div element, then:

Selenium.find_element_by_class_name(div.ur.class.name)
neer
  • 4,031
  • 6
  • 20
  • 34
Ryan
  • 11
  • 1