2016-06-02 12 views
1

У меня есть следующий HTML-код:Хо, я получаю html элемента списка, который == «некоторое значение»?

<ul class="list" role="listbox" id="list1"> 

    <li class="lvl2"> 
    <div class="lvl3" id="lvl3-nb-1"> 
     choice1 
    </div> 
    </li> 

    <li class="lvl2"> 
    <div class="lvl3" id="lvl3-nb-2"> 
     choice2 
    </div> 
    </li> 

    <li class="lvl2"> 
    <div class="lvl3" id="lvl3-nb-3"> 
     choice3 
    </div> 
    </li> 

</ul> 

я хотел бы получить HTML (внешний HTML, HTML + элемент, селектор, Xpath, это не имеет значения) элемента, который == "choice2"

Как это сделать с помощью RSelenium?

Благодаря

EDIT для осветления: в id s элементов списка являются динамическими (и в основном случайными), поэтому решение мне нужно не может ссылаться на их HTML или CSS. Тем не менее, я точно знаю значение choice1, choice2 и choice3 (и в основном все остальное, я знаю, что классы будут называться list, lvl2 и lvl3).

Покушение на воспроизводимый пример:

HTML:

<ul class="list" id="list1"> 
    <li class="lvl2"> 
    <div class="lvl3" id="n123"> 
     paul 
    </div> 
    </li> 
    <li class="lvl2"> 
    <div class="lvl3" id="n471"> 
     john 
    </div> 
    </li> 
    <li class="lvl2"> 
    <div class="lvl3" id="n951"> 
     ringo 
    </div> 
    </li> 
</ul> 

R:

> library(RSelenium) 
> startServer() 
> mybrowser <- remoteDriver() 
> mybrowser$open() 
> mybrowser$navigate("http://example.com") 
> list_of_beatles <- mybrowser$findElement(using = 'css selector', "ul#list.list1") 

> print(unlist(strsplit(as.character(list_of_beatles$getElementText()), "\n"))) 
[1] "paul"        "john"    
[3] "ringo" 

> # Let's say I want john's CSS selector, I'd want somethign kind of like that : 
> css_selector_of_this_thing(which(unlist(strsplit(as.character(list_reponse$getElementText()), "\n")) == "john")) 
> # Which would output, for instance "div#lvl3.n471" 
+0

Какой тег, который вы используете, немного расплывчато, но с использованием 'rvest',' html%>% read_html()%>% html_nodes ('# lvl3-nb-2')%>% html_text (trim = TRUE) '. Отрегулируйте, как вам нравится. – alistaire

+0

Воспроизводимый пример поможет. – pbahr

+0

Я редактировал вопрос, чтобы надеяться, сделать его более ясным. –

ответ

1

Если вы знаете, классы будут называться list, lvl2 и lvl3, а затем ваш текст будет быть в теге с классом lvl3, тогда вы можете использовать xpath:

result <- mybrowser$findElement(using = 'xpath', 
    ""//ul[@class = 'list']/*[@class = 'lvl2']/*[@class = 'lvl3'][contains(., 'john')]"") 

result$getElementAttribute("outerHTML")[[1]] 
# [1] "<div class=\"lvl3\" id=\"n471\">\n  john\n </div>"> 

result$getElementTagName()[[1]] # or result$getElementAttribute("tag")[[1]] 
# [1] "div" 

result$getElementAttribute("class")[[1]] 
# [1] "lvl3" 

result$getElementAttribute("id")[[1]] 
# [1] "n471" 

Или еще проще:

result2 <- mybrowser$findElement(using = 'xpath', 
    "//*[@class = 'lvl3'][contains(., 'john')]") 

Edit:

Согласно комментарий OP, есть случаи, когда необходимо различать john и saint john и johnny. Возможно, существуют способы, основанные на xpath, но я этого не понял (предложения/исправления приветствуются). Таким образом, я буду использовать некоторые регулярное выражение после первоначальной XPath:

# use findElements (plural) to get multiple elements 
result <- mybrowser$findElements(using = 'xpath', 
    "//*[@class = 'lvl3'][string()]") 

# loop through results and gather outerHTML to examine with regex 
choices <- unlist(lapply(result, function(x) x$getElementAttribute("outerHTML"))) 

Скажем, мы добавили johnny в другой записи, то choices будет выглядеть следующим образом:

#[1] "<div class=\"lvl3\" id=\"n123\">\n  paul\n </div>" 
#[2] "<div class=\"lvl3\" id=\"n471\">\n  john\n </div>" 
#[3] "<div class=\"lvl3\" id=\"n951\">\n  ringo\n </div>" 
#[4] "<div class=\"lvl3\" id=\"n952\">\n  johnny\n </div>" 

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

# \\W+ to look for non-word characters (i.e. [^[:alnum:]_]) 
# between the ">" and "<" that enclose the text 
choice <- which(grepl(">\\W+john\\W+<", choices, perl = TRUE)) 

result[[choice]]$getElementAttribute("outerHTML")[[1]] 
#[1] "<div class=\"lvl3\" id=\"n471\">\n  john\n </div>" 

Методы, показанные выше, будут работать, чтобы получить имя тега, класс и идентификатор здесь.

+0

Хорошо, кажется, работает почти так, как вам хотелось бы, большое спасибо. Одна небольшая проблема: элементы в списке могут быть похожими, например 'saint john',' john paul', 'johnny' и' john'.Кажется, 'contains' выберет первый, хотя я хочу точное совпадение. Любая идея о том, что использовать? Я вообще не знаком с XPath. –

+0

@fmalaussena Проверьте изменения, чтобы узнать, работает ли это для вас. – Jota