Ответ 1
Проблема: DOM Требуется <tbody/>
Теги
Firebug, инструмент разработчика Chrome, функции XPath в JavaScript и другие работают с DOM, а не с базовым исходным кодом HTML.
DOM для HTML требует, чтобы все таблицы строк, не содержащиеся в заголовке таблицы нижнего колонтитула (<thead/>
, <tfoot/>
), были включены в теги body тела <tbody/>
. Таким образом, браузеры добавляют этот тег, если он отсутствует при разборе (X) HTML. Например, Документация Microsoft DOM говорит
Элемент
tbody
отображается для всех таблиц, даже если таблица явно не определяет элементtbody
.
В другом ответе на stackoverflow содержится подробное объяснение .
С другой стороны, HTML не обязательно требует, чтобы тег использовался:
Начальный тег
tbody
всегда требуется, за исключением случаев, когда таблица содержит только одно тело таблицы, а также не имеет разделов таблицы или стопы.
Большинство процессоров XPath работают с необработанным XML
Исключая JavaScript, большинство процессоров XPath работают с необработанным XML, а не с DOM, поэтому не добавляют теги <tbody/>
. Кроме того, библиотеки парсера HTML, такие как tag-soup и htmltidy выводить только XHTML, а не "DOM-HTML".
Это распространенная проблема, размещенная в Stackoverflow для PHP, Ruby, Python, Java, С#, Google Docs (электронных таблиц) и многих других. Селен работает внутри браузера и работает на DOM - так что это не затрагивается!
Воспроизведение проблемы
Сравните источник, показанный Firebug (или инструментами Chrome Dev) с тем, который вы получаете, щелкнув правой кнопкой мыши и выбрав "Показывать источник страницы" (или что бы он ни называл в ваших браузерах) - или используя curl http://your.example.org
на командная строка. Latter, вероятно, не содержит никаких элементов <tbody/>
(они редко используются), Firebug всегда будет показывать их.
Решение 1: Удалить /tbody
Шаг оси
Проверьте, действительно ли таблица, на которую вы застряли, не содержит элемент <tbody/>
(см. последний абзац). Если это так, у вас, вероятно, есть еще одна проблема.
Теперь удалите шаг оси /tbody
, поэтому ваш запрос будет выглядеть как
//table[@id="example"]/tr[2]/td[1]
Решение 2: Пропустить <tbody/>
Теги
Это довольно грязное решение и вероятность неудачи для вложенных таблиц (может переходить во внутренние таблицы). Я бы рекомендовал это в очень редких случаях.
Заменить шаг оси /tbody
на шаг потомка:
//table[@id="example"]//tr[2]/td[1]
Решение 3: Разрешить ввод с и без <tbody/>
Тэги
Если вы заранее не уверены в своей таблице или используете запрос как в "источнике HTML", так и в контексте DOM; и не хотите/не можете использовать хак из решения 2, предоставить альтернативный запрос (для XPath 1.0) или использовать "необязательный" шаг оси (XPath 2.0 и выше).
- XPath 1.0:
//table[@id="example"]/tr[2]/td[1] | //table[@id="example"]/tbody/tr[2]/td[1]
- XPath 2.0:
//table[@id="example"]/(tbody, .)/tr[2]/td[1]