Мне интересно, есть ли способ легко получить текст, который зажат между двумя дочерними элементами с текстом? В этом конкретном случае я хочу извлечь текст USD
.
<div class="indemandProgress-raised ng-binding">
<span class="indemandProgress-raisedAmount ng-binding" gogo-test="raised">
$6,811,034
</span>
USD
<span class="ng-binding">
total funds raised
</span>
</div>
Фактический формат кода в браузере
<div class="indemandProgress-raised ng-binding">
<span class="indemandProgress-raisedAmount ng-binding" gogo-test="raised">$6,811,034</span> USD <span class="ng-binding">total funds raised</span>
</div>
Возможно ли это с помощью XPATH, или мне нужно извлечь весь текст и затем проанализировать его?
Он должен работать с Селеном.
Попробуйте использовать xpath 2. 0+:
//div[@class="indemandProgress-raised ng-binding"]/text()
В Selenium вы не можете использовать XPath, который возвращает атрибуты или текстовые узлы, поскольку поддерживаются только узлы.
Чтобы получить текст, который вы хотите, вы можете использовать Javascript, чтобы извлечь его из текстового узла. Или выберите узел, а затем используйте .text
result = browser.find_element_by_xpath('//div[contains(@class, "indemandProgress-raisedAmount")]').text.split()[1]
Поэтому, в конечном счете, невозможно использовать XPath/text() в Selenium, и вам нужно полагаться на альтернативные методы, как указано.
Вы уже приняли ответ, но обратите внимание, что text.split()[1]
является довольно ненадежным решением и может быть неприменим в других случаях (в большинстве случаев). Например, если первый текстовый узел содержит пробелы
$ 6,811,034
Вы можете попробовать это решение:
element = browser.find_element_by_class_name('indemandProgress-raisedAmount')
result = browser.execute_script('return arguments[0].childNodes[2].textContent;', element).strip()
Обратите внимание, что div
имеет следующие 5 дочерних узлов:
0
)span
узел (индекс 1
)"USD"
(индекс 2
)span
(индекс 3
)4
) Вам нужно получить текстовое содержимое третьего дочернего узла и childNodes[2].textContent
позволяет вам делать это
browser.find_element_by_xpath(...).text
всегда возвращает результат, похожий на $107,866 USD total funds raised
в $107,866 USD total funds raised
.
result = browser.execute_script('return arguments[0].childNodes[2].textContent;', element).strip()
, element
передается в качестве arguments
?
Вы не можете сделать это с помощью XPath, но вы можете использовать Javascript Executor и получить текстовый узел. Вы не указали язык, поэтому здесь вы можете использовать метод С#:
/// <summary>
/// Returns the text of the specified child text node.
/// </summary>
/// <param name="parentElement">The parent <see cref="IWebElement"/> of the desired text node.</param>
/// <param name="index">The index of the childNode collection relative to parentElement</param>
/// <returns>The text of the specified child text node.</returns>
public string GetChildTextNode(IWebElement parentElement, int index = 0)
{
string s = (string)((IJavaScriptExecutor)driver).ExecuteScript("return arguments[0].childNodes[arguments[1]].textContent;", parentElement, index);
return s.Trim();
}
В этом случае вы бы назвали это как
IWebElement e = Driver.FindElement(By.CssSelector("div.indemandProgress-raised"));
string s = GetChildTextNode(e, 2);
WebDriverException: Message: TypeError: Expected an element or WindowProxy, got: [object Text] {}
.text
... в любом случае, JS бесполезен, поскольку я могу просто использоватьx = browser.find_element_by_xpath(...).text.split()[1]
.