Home > OS >  Python find_element in find_elements problem part 3?
Python find_element in find_elements problem part 3?

Time:03-15

Good day everyone:

I’d like to get data from the url (sorry its encoded, cause online editor always report its a spam)

after click the basketball of mainmenu and close AD then click the date combobox menu and select the date by date

Now my code try to get all data everyday until yesterday , which include the following fields

  1. date
  2. league
  3. time / status (depend on odd or even line)
  4. team / score1 ~ score5 / score total

After got all data , will save to SQL DB

Below is my code

import time

from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException        

driver = webdriver.Chrome()
driver.set_window_size(1500, 1350)
delay = 10

# open url (sorry for the url , cause system always report its a spam)
url1 = "http"
url2 = "888.net/spo"
url3 = "s://web2.sa8"
url4 = "rt/Games.a"
url5 = "evice=pc"
url6 = "spx?lang=3&d"
driver.get(url1   url3   url2   url4   url6   url5)

# jump to basketball
locator = (By.XPATH, '//*[@id="menuList"]/div/ul/li[3]/div[2]/a[1]') 
pointer = WebDriverWait(driver, delay).until(EC.presence_of_element_located(locator),"element not found")
actions = ActionChains(driver)
actions.click(pointer).perform()
time.sleep(1)

# close AD
locator = (By.ID, 'btn_close') 
pointer = WebDriverWait(driver, delay).until(EC.presence_of_element_located(locator),"element not found")
actions = ActionChains(driver)
actions.click(pointer).perform()

# wait for date 
locator = (By.XPATH, './/*[@id="dateOption"]')
pointer = WebDriverWait(driver, delay).until(EC.presence_of_element_located(locator),"element not found")

all_dates = []
_dates = driver.find_elements(By.XPATH, './/*[@id="dateOption"]/a[*]')
for date in _dates:
    rel = date.get_attribute("rel")
    all_dates.append(rel)
    #print(rel)
#print(*all_dates, sep = ", ") 

#_dates = driver.find_elements(By.XPATH, './/*[@id="dateOption"]/a[*]')
date_counter = 1
for date in range(len(_dates)-8): # until yesterday
    # click pull down date menu
    locator = (By.XPATH, './/*[@id="chooseDate"]')
    pointer = WebDriverWait(driver, delay).until(EC.presence_of_element_located(locator), "element not found")
    actions.move_to_element(pointer).perform()
    actions.click(pointer).perform()

    # click date#n
    temp = './/*[@id="dateOption"]/a[' str(date_counter) ']/span[1]'
    #print("XPATH=",temp)
    locator = (By.XPATH, temp)
    pointer = WebDriverWait(driver, delay).until(EC.presence_of_element_located(locator), "element not found")
    actions.move_to_element(pointer).perform()
    actions.click(pointer).perform()
    date_counter  = 1

    leagues = driver.find_elements(By.XPATH, './/*[@id="scheduleBottom"]/table[*]')
    print(all_dates[date_counter],'\tdaily leagues:', len(leagues))
    league_counter = 1
    for league in leagues:
        # print("\tleague.text=",league.text,"\n")
        #_rows = Block.find_elements(By.TAG_NAME, "tr")
        league_Title = league.find_element(By.XPATH ,'//*[@id="scheduleBottom"]/table[*]/caption/a')
        #time.sleep(2)
        _rows = league.find_elements(By.XPATH, ".//*[contains(@id, '_mainRow') or contains(@id, '_secondRow')]")
        print("\tleague:", league_Title.text) #, '(', len(_rows), ')')
        row_counter = 1
        for row in _rows:
            #print("\t\trow #",row_counter, row.text.replace('\n', ' | '))  # <- clean text
            if row_counter %2 > 0:
                _time   = row.find_element(By.XPATH, './/*[@id="*_gd"]') 
                _status = row.find_element(By.XPATH, './/*[@id="*_gs"]')
            _team   = row.find_element(By.XPATH, './/*//*[@id="_ta"]')
            _score1 = row.find_element(By.XPATH, './/*[@id="*_rsa1"]')
            _score2 = row.find_element(By.XPATH, './/*[@id="*_rsa2"]')
            _score3 = row.find_element(By.XPATH, './/*[@id="*_rsa3"]')
            _score4 = row.find_element(By.XPATH, './/*[@id="*_rsa4"]')
            _score5 = row.find_element(By.XPATH, './/*[@id="*_rsa5"]')
            _scorea = row.find_element(By.XPATH, './/*[@id="*_ra"]"]')

            # insert to DB
            row_counter  = 1
        league_counter  = 1
    print('---')

time.sleep(15)
driver.quit()

and I got the error message

2022/03/10      daily leagues: 45
        league: NBA
Traceback (most recent call last):
  File "/Users/andy/Python/sa8888 #5.7.py", line 85, in <module>
    _time   = row.find_element(By.XPATH, './/*[@id="*_gd"]') 
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/selenium/webdriver/remote/webelement.py", line 735, in find_element
    return self._execute(Command.FIND_CHILD_ELEMENT,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/selenium/webdriver/remote/webelement.py", line 710, in _execute
    return self._parent.execute(command, params)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 424, in execute
    self.error_handler.check_response(response)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/selenium/webdriver/remote/errorhandler.py", line 247, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":".//*[@id="*_gd"]"}
  (Session info: chrome=96.0.4664.110)

What should I do to fix it? Thanks in advance

CodePudding user response:

* will not work in string "*_gd" in @id="*_gd" and other xpaths.

You have to use contains() - './/*[contains(@id, "_gd")]'


BTW:

Selenium probably uses XPath 1.2 because it has also starts-with()
but it doesn't have ends-with() (which exists in XPath 2.0)

Stack Overflow: XPath testing that string ends with substring?

  • Related