2014-02-18 4 views
2

Я новичок в nokogiri и до сих пор больше всего знаком с CSS-селекторами, я пытаюсь разобрать информацию из таблицы, ниже - образец таблицы и кода, который я использую, я 'm застрял в соответствующем if-заявлении, поскольку он, кажется, возвращает все содержимое таблицы.nokogiri + mechanize css селектор по тексту

Таблица:

<div class="holder"> 
    <div class ="row"> 
    <div class="c1"> 
    <!-- Content I Don't need --> 
    </div> 
    <div class="c2"> 
    <span class="data"> 
    <!-- Content I Don't Need --> 
    <span class="data"> 
    </div> 
</div> 
... 
<div class="row"> 
    <div class="c1"> 
    SPECIFIC TEXT 
    </div> 
    <div class="c2"> 
    <span class="data"> 
    What I want 
    </span> 
    </div> 
</div> 
</div> 

Мой скрипт (если конкретный текст найден в таблице он возвращает все «div.c2 span.data» переменную - так что я либо зажмурил свои знания делают петли или если заявления)

data = [] 
page.agent.get(url) 
page.search('div.row').each do |row_data| 
if (row_data.search('div.c1:contains("/SPECIFIC TEXT/")').text.strip 
    temp = row_data.search('div.c2 span.data').text.strip 
    data << temp 
end 
end 
+0

Текущий выход '' * п + 'Что я want', ожидается выход' Что я want' – Elliott

+0

Да .. я что .. Пожалуйста, попробуйте решения ниже –

+0

Возможно ли, что в таблице будет более одного КОНКРЕТНОГО ТЕКСТА? Или вы ищете только один матч? –

ответ

4

Там нет необходимости останавливать и вставить рубин логику, когда вы можете извлечь то, что вам нужно в одном селекторе CSS.

data = page.search('div.row > div.c1:contains("SPECIFIC TEXT") + div.c2 span.data') 

Это будет включать только те, которые соответствуют селектору (например, следуйте СПЕЦИФИЧЕСКОМ ТЕКСТУ).

Вот где ваша логика может пойти не так:

Этот код

if (row_data.search('div.c1:contains("SPECIFIC TEXT")'... 
    temp = row_data.search('div.c2 span.data')... 

сначала выполняет поиск в строке для конкретного текста, а затем, если они совпадают, возвращает все строки, соответствующие второй запрос, который имеет та же самая отправная точка. Ключ - это + в селекторе CSS выше, который будет возвращать элементы, следующие сразу (например, следующий элемент сиблинга). Разумеется, я предполагаю, что следующий элемент всегда то, что вы хотите.

+1

Да .. вам нужно иметь '+' там .. Теперь это сработает. –

+0

Я добавил '+', и он отлично работал, спасибо – Elliott

2

я сделаю

require 'nokogiri' 

html = <<_ 
<div class="holder"> 
    <div class ="row"> 
    <div class="c1"> 
    <!-- Content I Don't need --> 
    </div> 
    <div class="c2"> 
    <span class="data"> 
    <!-- Content I Don't Need --> 
    <span class="data"> 
    </div> 
</div> 
<div class="row"> 
    <div class="c1"> 
    SPECIFIC TEXT 
    </div> 
    <div class="c2"> 
    <span class="data"> 
    What I want 
    </span> 
    </div> 
</div> 
</div> 
_ 

doc = Nokogiri::HTML(html) 
css_string = 'div.row > div.c1[text()*="SPECIFIC TEXT"] + div.c2 span.data' 
doc.at(css_string).text.strip 
# => "What I want" 

Как эти селекторы будут работать здесь -

  • [name*="value"] - Выбирает элементы, которые имеют указанный атрибут со значением, содержащим заданную подстроку.

  • Child Selector (“parent > child”) - Выбирает все прямые дочерние элементы, указанные «дочерним» элементом, указанным «parent».

  • Next Adjacent Selector (“prev + next”) - Выбирает все следующие элементы, соответствующие «следующему», которым сразу предшествует родственный «prev».

  • Class Selector (“.class”) - Выбирает все элементы данного класса.

  • Descendant Selector (“ancestor descendant”) - Выбирает все элементы, которые являются потомками данного предка.

+0

Я изначально сделал 'temp = doc.at_css ('div.row> div.c1: contains (" SPECIFIC TEXT ") + div.c2 span.date') .текст.strip', и я получил неопределенный метод 'at_css' error от Mechanize – Elliott

+0

@Elliott Я использовал здесь' at_css' нарочно, если вы хотите искать кратные узлы, используйте '# css'. –

+0

@Arup, не все методы Нокогири доступны из Mechanize. –

Смежные вопросы