Использование Nokogiri для разделения контента по тегам BR - PullRequest
6 голосов
/ 14 августа 2011

У меня есть фрагмент кода, который я пытаюсь проанализировать с помощью nokogiri, который выглядит следующим образом:

<td class="j">
    <a title="title text1" href="http://link1.com">Link 1</a> (info1), Blah 1,<br>
    <a title="title text2" href="http://link2.com">Link 2</a> (info1), Blah 1,<br>
    <a title="title text2" href="http://link3.com">Link 3</a> (info2), Blah 1 Foo 2,<br>
</td>

У меня есть доступ к источнику td.j, используя что-то вроде этого: data_items = doc.css("td.j")

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

Мне было интересно, есть ли лучший способ сделать это, возможно, используя только nokogiri?Даже если бы я мог использовать nokogiri, чтобы высосать 3 позиции, мне было бы легче, так как я мог бы просто выполнить регулярное выражение для анализа .content.

Не знаете, как использовать Nokogiri для захвата строк, заканчивающихся на br - должен ли я использовать xpaths?Любое направление ценится!спасибо

Ответы [ 2 ]

17 голосов
/ 15 августа 2011

Я не уверен насчет смысла использования массива хэшей, и без примера я не могу что-то предложить.Однако для разбиения текста на теги <br> я бы сделал это следующим образом:

require 'nokogiri'

doc = Nokogiri::HTML('<td class="j">
    <a title="title text1" href="http://link1.com">Link 1</a> (info1), Blah 1,<br>
    <a title="title text2" href="http://link2.com">Link 2</a> (info1), Blah 1,<br>
    <a title="title text2" href="http://link3.com">Link 3</a> (info2), Blah 1 Foo 2,<br>
</td>')

doc.search('br').each do |n|
  n.replace("\n")
end
doc.at('tr.j').text.split("\n") # => ["", "    Link 1 (info1), Blah 1,", "Link 2 (info1), Blah 1,", "Link 3 (info2), Blah 1 Foo 2,"]

Это приблизит вас к хешу:

Hash[*doc.at('td.j').text.split("\n")[1 .. -1].map{ |t| t.strip.split(',')[0 .. 1] }.flatten] # => {"Link 1 (info1)"=>" Blah 1", "Link 2 (info1)"=>" Blah 1", "Link 3 (info2)"=>" Blah 1 Foo 2"}
1 голос
/ 15 августа 2011

Если ваши данные действительно такие регулярные и вам не нужны атрибуты из элементов <a>, то вы можете анализировать текстовую форму каждой ячейки таблицы, не беспокоясь об элементах <br> вообще.

С учетом некоторого HTML-кода в html:

<table>
    <tbody>
        <tr>
            <td class="j">
                <a title="title text1" href="http://link1.com">Link 1</a> (info1), Blah 1,<br>
                <a title="title text2" href="http://link2.com">Link 2</a> (info1), Blah 1,<br>
                <a title="title text2" href="http://link3.com">Link 3</a> (info2), Blah 1 Foo 2,<br>
            </td>
            <td class="j">
                <a title="title text1" href="http://link4.com">Link 4</a> (info1), Blah 2,<br>
                <a title="title text2" href="http://link5.com">Link 5</a> (info1), Blah 2,<br>
                <a title="title text2" href="http://link6.com">Link 6</a> (info2), Blah 2 Foo 2,<br>
            </td>
        </tr>
        <tr>
            <td class="j">
                <a title="title text1" href="http://link7.com">Link 7</a> (info1), Blah 3,<br>
                <a title="title text2" href="http://link8.com">Link 8</a> (info1), Blah 3,<br>
                <a title="title text2" href="http://link9.com">Link 9</a> (info2), Blah 3 Foo 2,<br>
            </td>
            <td class="j">
                <a title="title text1" href="http://linkA.com">Link A</a> (info1), Blah 4,<br>
                <a title="title text2" href="http://linkB.com">Link B</a> (info1), Blah 4,<br>
                <a title="title text2" href="http://linkC.com">Link C</a> (info2), Blah 4 Foo 2,<br>
            </td>
        </tr>
    </tbody>
</table>

Вы можете сделать это:

chunks = doc.search('.j').map { |td| td.text.strip.scan(/[^,]+,[^,]+/) }

и иметь это:

[
    [ "Link 1 (info1), Blah 1", "Link 2 (info1), Blah 1", "Link 3 (info2), Blah 1 Foo 2" ],
    [ "Link 4 (info1), Blah 2", "Link 5 (info1), Blah 2", "Link 6 (info2), Blah 2 Foo 2" ],
    [ "Link 7 (info1), Blah 3", "Link 8 (info1), Blah 3", "Link 9 (info2), Blah 3 Foo 2" ],
    [ "Link A (info1), Blah 4", "Link B (info1), Blah 4", "Link C (info2), Blah 4 Foo 2" ]
]

в chunks. Затем вы можете преобразовать это в любую хеш-форму, которая вам нужна.

...