Как найти все «не родительские» узлы в xpath без преобразования в строку? - PullRequest
1 голос
/ 06 апреля 2020

Через некоторое время go я ответил на мой вопрос: Как мне найти все узлы без дочерних элементов (начиная с не root узла!) В xpath / R? после некоторой попытки.

Но иногда я нахожу исключения:

library(magrittr)
library(xml2)
url <- "https://kcsouthern.silkroad.com/epostings/index.cfm?fuseaction=app.jobsearch"
node <- url %>% 
   read_html %>% 
   html_nodes(xpath = "/html/body/div[1]/div/div[2]/div[3]/table/tr[2]")

Я не нахожу все узлы без дочерних элементов, как это:

> node %>% html_nodes(xpath = "*//*[not(descendant::*)]")
{xml_nodeset (1)}
[1] <a id="jobTitle_220359" href="index.cfm?fuseaction=app.jobinfo&amp;jobid=…

Но после преобразования в строку и "re -читать "как XML я делаю:

> node %>% 
     toString %>% 
     read_html %>% 
     html_nodes(xpath = "*//*[not(descendant::*)]")
{xml_nodeset (3)}
[1] <td align="center" class="cssSearchResultsBody">220359-021</td>
[2] <a id="jobTitle_220359" href="index.cfm?fuseaction=app.jobinfo&amp;jobid...
[3] <td align="left" class="cssSearchResultsBody">Kansas City, Missouri, United States</td>

Редактировать: Дальнейший анализ, касающийся ответа Э. Уайста:

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

> url %>% 
+   GET %>% 
+   content(as = "text") %>% 
+   XML::htmlParse() %>% 
+   XML::xpathSApply(path = "(//tr[@class='cssSearchResultsHighlight'])[1]//*[not(.//*)]")
[[1]]
<td align="center" class="cssSearchResultsBody">220359-021</td> 

[[2]]
<a id="jobTitle_220359" href="....">SAP HR/Payroll Specialist</a> 

[[3]]
<td align="left" class="cssSearchResultsBody">Kansas City, Missouri, United States</td> 

Теперь эквивилиант с xml2 / rvest: (тоже, кажется, работает)

> url %>% 
+   read_html %>% 
+   html_nodes(xpath = "//tr[@class='cssSearchResultsHighlight'][1]//*[not(.//*)]")
{xml_nodeset (3)}
[1] <td align="center" class="cssSearchResultsBody">220359-021</td>
[2] <a id="jobTitle_220359" href="index.cfm?fuseaction=app.jobinfo&amp;jobid=220359&amp...
[3] <td align="left" class="cssSearchResultsBody">Kansas City, Missouri, United States</td>

Скорее, проблема в том, что человек начинает поиск с не root узел?

> url %>% 
+   read_html %>% 
+   html_nodes(xpath = "//tr[@class='cssSearchResultsHighlight'][1]") %>% 
+   html_nodes(xpath = "*[not(.//*)]")
{xml_nodeset (2)}
[1] <td align="center" class="cssSearchResultsBody">220359-021</td>
[2] <td align="left" class="cssSearchResultsBody">Kansas City, Missouri, United States</td>

1 Ответ

1 голос
/ 07 апреля 2020

Полагаю, проблема связана с xml2 или rvest. У меня есть 3 результата непосредственно с xpathSApply на моем разобранном объекте (htmlParse). XPath:

(//tr[@class='cssSearchResultsHighlight'])[1]//*[not(.//*)]

Выход:

Trucks

R код:

library(httr)
library(XML)
page=GET("https://kcsouthern.silkroad.com/epostings/index.cfm?fuseaction=app.jobsearch")
parsed=htmlParse(content(page,as = "text"))
xpathSApply(parsed,"(//tr[@class='cssSearchResultsHighlight'])[1]//*[not(.//*)]")

РЕДАКТИРОВАТЬ 2: В На самом деле проблем нет вообще. Что возвращает Rvest просто отлично. Он выводит, что означает выражение XPath. Если мы изолируем первый элемент tr, у нас будет.

<tr class="cssSearchResultsHighlight">
<td align="center" class="cssSearchResultsBody">220359-021</td>
<td align="left" class="cssSearchResultsBody"><a id="jobTitle_220359" href="index.cfm?fuseaction=app.jobinfo&amp;jobid=220359&amp;source=ONLINE&amp;JobOwner=992452&amp;company_id=16021&amp;version=1&amp;byBusinessUnit=&amp;bycountry=&amp;bystate=&amp;byRegion=&amp;bylocation=&amp;keywords=&amp;byCat=&amp;proximityCountry=&amp;postalCode=&amp;radiusDistance=&amp;isKilometers=&amp;tosearch=no&amp;city=" class="cssSearchResultsBody">SAP HR/Payroll Specialist</a></td>
<td align="left" class="cssSearchResultsBody">Kansas City, Missouri, United States</td> 
</tr>

Следующий код вернет 1 результат (элемент a) из этого tr (ищите элемент, потомок другого элемента (потомок tr) ), и который не имеет дочернего элемента):

url %>%
  read_html %>%
  html_nodes(xpath = "//tr[@class='cssSearchResultsHighlight'][1]") %>%
  html_nodes(xpath = "*//*[not(.//*)]")

Следующий код вернет 2 результата (первый и третий элемент td) из этого tr (ищите элемент, потомок tr, и который не имеет дочернего элемента):

url %>%
  read_html %>%
  html_nodes(xpath = "//tr[@class='cssSearchResultsHighlight'][1]") %>%
  html_nodes(xpath = "*[not(.//*)]")

Следующий код вернет 3 результата (первый и третий элемент td и элемент a) из этого tr (начиная с tr, ищите в любом месте элемент, который не имеет ребенок):

url %>%
  read_html %>%
  html_nodes(xpath = "//tr[@class='cssSearchResultsHighlight'][1]") %>%
  html_nodes(xpath = ".//*[not(.//*)]")

XPRvest Код № 3, вероятно, то, что вы ищете. Примечание: не забудьте исправить первое выражение XPath: /html/body/div[1]/div/div[2]/div[3]/table/tr[2] должно быть /html/body/div[1]/div/div[2]/div[3]/table//tr[2]

...