Если вы хотите выбрать целевые узлы одним «волхвом c xpath», вот оно:
from selenium import webdriver
country = 'South Africa'
driver = webdriver.Chrome()
driver.get("https://www.punters.com.au/form-guide/2020-01-14/")
xpath = f"//tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='{country}']][position()<=(count(//tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='{country}']])-count(//tr[preceding-sibling::tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='{country}'] and contains(@class, 'upcoming-race__row--country')][1]])-count(//tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='{country}'] and contains(@class, 'upcoming-race__row--country')][1]))]/td[1]"
found_nodes = driver.find_elements_by_xpath(xpath)
driver.close()
Давайте опишем, что делает этот XPath на примере Новой Зеландии :
Я сделаю псевдонимы блоков XPath для лучшей читаемости концепции результата в конце.
1. Первый часть о поиске с чего начать - давайте найдем узел с новозеландским заголовком (давайте назовем его TARGET_XPATH) :
`//tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='New Zealand']]`
2. Теперь нам нужно ограничить найденные результаты только одной страной. Лучший выбор для этой операции в текущем случае, я знаю, - оператор «позиция». Мы должны предоставить позицию последнего полезного элемента (перед первым "trashy") в наших результатах. Давайте вычислим это:
`(count(//tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='New Zealand']])-count(//tr[preceding-sibling::tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='New Zealand'] and contains(@class, 'upcoming-race__row--country')][1]])-count(//tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='New Zealand'] and contains(@class, 'upcoming-race__row--country')][1]))`
Здесь мы считаем три типа элементов:
a. Количество узлов после заголовка нашей страны (с именем COUNT_TOTALS) :
count(//tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='New Zealand']])
b. Количество узлов после первого «мусорного» узла (с именем COUNT_AFTER_TRASHY_HEADER) :
count(//tr[preceding-sibling::tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='New Zealand'] and contains(@class, 'upcoming-race__row--country')][1]])
c. И мы должны проверить наличие любого «мусорного» узла, в случае, когда мы ищем расы для последней страны в таблице - у него не будет следующего «мусорного» узла (с именем COUNT_TRASHY_HEADER) :
count(//tr[preceding-sibling::tr[contains(@class, 'upcoming-race__row--country')]/td/img[@title='New Zealand'] and contains(@class, 'upcoming-race__row--country')][1])
3. Используйте наш счетчик в качестве фильтра:
TARGET_XPATH[position()<=(COUNT_TOTALS - COUNT_AFTER_TRASHY_HEADER - COUNT_TRASHY_HEADER)]