Как извлечь текстовое содержимое между двумя узлами - PullRequest
1 голос
/ 20 ноября 2019

Я хочу извлечь текст, содержащийся в красном и зеленом прямоугольниках, как показано на скриншоте ниже, NB: текст не содержится в открывающем и закрывающем теге

http://temperate.theferns.info/plant/Acacia+omalophylla

enter image description here

например, для текста зеленого прямоугольника я протестировал этот запрос xpath и следующий код (python / selenium):

greenrec_xpath = "//*[preceding::h3[contains(text(), 'General Information')] and following::h3[contains(text(), 'Known Hazards')]]"
driver.find_elements_by_xpath(greenrec_xpath)

но не дало ожидаемых результатов

нет идей!

Ответы [ 3 ]

1 голос
/ 21 ноября 2019
greenrec_xpath = 
 "//*[preceding::h3[contains(text(), 'General Information')] 
    and following::h3[contains(text(), 'Known Hazards')]]"

Вы очень близки к тому, чтобы найти выражение XPath, которое выбирает нужные текстовые узлы:

Использование :

//*[preceding::h3[1][contains(., 'General Information')] 
  and following::h3[1][contains(., 'Known Hazards')]
   ]/text()[normalize-space()]

Имейте в виду, что это выражение выделяет множество текстовых узлов (в данном конкретном случае 5).

Если вы хотите получить одну строку, вам нужно получить строковые значения каждого выделенного текстаобъединить и объединить их вместе в одну строку. В случае, если вы можете использовать только XPath 1.0, вам нужно будет выполнить эту конкатенацию строк в коде вызывающего программирования (не XPath).

Если вы можете использовать XPath 2.0 (или более позднюю версию), используйте :

string-join(
            //*[preceding::h3[1][contains(., 'General Information')] 
              and following::h3[1][contains(., 'Known Hazards')]
               ]/text()[normalize-space()]/string(.)
            ,
             ''
           )
1 голос
/ 21 ноября 2019

Чтобы извлечь текст Классификация рода Acacia ... , так как элемент является текстовым узлом, вам нужно вызвать WebDriverWait для visibility_of_element_located(), и вы можете использовать следующие Стратегия локатора :

  • Кодовый блок:

    driver.get("http://temperate.theferns.info/plant/Acacia+omalophylla")
    print(driver.execute_script('return arguments[0].childNodes[11].textContent;', WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.PageBox")))).strip())
    
  • Консольный вывод:

    Classification of the genus Acacia (in the wider sense) has been subject to considerable debate. It is generally agreed that there are valid reasons for breaking it up into several distinct genera, but there has been disagreement over the way this should be done. As of 2017, it is widely (but not completely) accepted that the section that includes the majority of the Australian species (including this one) should retain the name Acacia, whilst other sections of the genus should be transferred to the genera Acaciella, Mariosousa, Senegalia and Vachellia[
    
1 голос
/ 20 ноября 2019

Если рядом с текстом нет ближайших окружающих скобок, он называется текстовым узлом, и его немного сложнее найти, так как к нему нельзя получить прямой доступ, например, как вы пытаетесь это сделать. Обычно мне нужно найти местоположение ближайшего родителя и получить от него текст. Это становится немного сложнее, если под этим родителем есть несколько текстовых узлов, и, как правило, требуется некоторый анализ / разбиение после получения всего текста.

В качестве альтернативы, если вы находитесь в ситуации, когда вы можете гарантировать, что ваш текстузел содержит некоторый определенный текст, вы можете поменять text() с . и сделать xpath таким образом. Например: //*[contains(.,'Acacia omalophylla')]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...