Selenium: как обрабатывать некорректные селекторы CSS в DOM - PullRequest
0 голосов
/ 21 февраля 2020

Я очищаю веб-сайт с Selenium / Python3, веб-сайт использует только недействительные селекторы, такие как:

<input id="egg:bacon:SPAM" type="text"/>
<input id="egg:sausages:SPAM:SPAM" type="text"/>

(недопустимые части egg:bacon:SPAM & egg:sausages:SPAM:SPAM)

Я пытался выбрать эти теги с помощью:

driver.find_element_by_css_selector('input#egg:bacon:SPAM')

Но, конечно, я получаю selenium.common.exceptions.InvalidSelectorException


Я также пытался использовать xpath, чтобы получить мои теги, он работает с:

driver.find_element_by_xpath('//input[@id="egg:bacon:SPAM"]')

Но мой код основан на домашней библиотеке, основанной на селекторах CSS. Добавление поддержки XPATH потребует добавления ~ 200 строк кода (без учета юнит-тестов, документации и т. Д. c ..) только для того, чтобы справиться с этим неправильным, а не с общим поведением c.

Плюс, очистка этого Веб-сайт является частью более крупного проекта, в котором только этот конкретный c веб-сайт использует такие CSS селекторы, поэтому большое количество усилий для одного веб-сайта на 10 доставляет мне неудобство.


Я мог бы использовать что-то вроде find_element_by_css_selector('.foo > input:nth-child(2)'), но это довольно сложно, и любое небольшое обновление DOM может сломать скребок.

Есть ли какой-нибудь clean способ обработки недопустимых css селекторов через Selenium с использованием find_element_by_css_selector или я обречен использовать XPATH для этого сайта?

Ответы [ 2 ]

2 голосов
/ 21 февраля 2020

Они все действительны. Вам нужно экранировать специальные символы или использовать кавычки:

driver.find_element_by_css_selector('input[id="egg:bacon:SPAM"]')
driver.find_element_by_css_selector('input#egg\:bacon\:SPAM')
1 голос
/ 21 февраля 2020

Чтобы идентифицировать элемент с атрибутом id, содержащим зарезервированные символы, например, яйцо: бекон: СПАМ , яйцо: сосиски: СПАМ: СПАМ вы можете используйте динамические c со следующими подстановочными знаками:

  • ^: для указания значения атрибута начинается с
  • *: для указания значения атрибута содержит
  • $: для указания Значение атрибута оканчивается на

Решение

Можно использовать следующие решения:

  • Для идентификации элемент <input id="egg:bacon:SPAM" type="text"/>:

    driver.find_element_by_css_selector("input[id^='egg'][id*='bacon'][id$='SPAM']")
    
  • Для идентификации элемента <input id="egg:sausages:SPAM:SPAM" type="text"/>:

    driver.find_element_by_css_selector("input[id^='egg'][id*='sausages'][id$='SPAM']")
    

Ссылка

Вы можете найти пару соответствующих обсуждений в:

...