Как заполнить массив текстом из HTML-страниц в ruby

Я использовал рубиновый камень nokogiri для создания html-файла только для текста в классе tableData. HTML-код настроен так:

<div class="table-wrap">
   <table class="table">
     <tbody>
        <tr>
           <td class="tableData"> Jane Doe</td>
           <td class="tableData"> 01/01/2017</td>
           <td class="tableData">01/09/2017 </td>
           <td class="tableData">Vacation</td>
        </tr>
        <tr>
           <td class="tableData">John Doe</td>
           <td class="tableData"> 01/01/2017</td>
           <td class="tableData">01/09/2017 </td>
           <td class="tableData">Vacation</td>
        </tr>
     </tbody>
   </table>
</div>

и код, который я использовал для webscrape, выглядит так:

vt = page.css("td[class='tableData']").text
puts vt

Что дает этот вывод:

Jane Doe 01/01/201701/09/2017 VacationJohn Doe 01/01/201701/09/2017 Vacation

Я хочу заполнить массив в массиве только с 4 текстовыми значениями, относящимися к каждому человеку. Который должен выглядеть так:

[[Jane Doe, 01/01/2017, 01/09/2017, Vacation], [John Doe, 01/01/2017, 01/09/2017, Vacation]]

Я новичок в кодировании, и я не уверен, как создать цикл for для итерации либо самого html-кода, либо переменной vt для создания массива массивов. Я знаю, что после цикла for задействованы некоторые операторы push, но это фактическая структура цикла for, из-за которой у меня возникают проблемы при их создании. Если бы вы могли дать какое-то объяснение в своем ответе о том, как работает цикл for в этой ситуации, это было бы очень полезно.

2 ответа

Решение

Это базовая структура, которая вам нужна. map нужно:

html=%q(<div class="table-wrap">
   <table class="table">
     <tbody>
        <tr>
           <td class="tableData"> Jane Doe</td>
           <td class="tableData"> 01/01/2017</td>
           <td class="tableData">01/09/2017 </td>
           <td class="tableData">Vacation</td>
        </tr>
        <tr>
           <td class="tableData">John Doe</td>
           <td class="tableData"> 01/01/2017</td>
           <td class="tableData">01/09/2017 </td>
           <td class="tableData">Vacation</td>
        </tr>
     </tbody>
   </table>
</div>)

require 'nokogiri'
doc = Nokogiri::XML(html)
array = doc.xpath('//tr').map do |tr|
  tr.xpath('td').map{ |td| td.text }
end

p array
# [[" Jane Doe", " 01/01/2017", "01/09/2017 ", "Vacation"], ["John Doe", " 01/01/2017", "01/09/2017 ", "Vacation"]]

Попробуйте проанализировать фрагмент как XML, найти все элементы tr через XPath и собрать их потомки td//text():

require 'nokogiri'
doc = Nokogiri::XML(get_html_snippet)
data = doc.xpath('//tr').map do |tr|
  tr.xpath('td').map { |td| td.text.strip }
end
data # => [["Jane Doe", "01/01/2017", "01/09/2017", "Vacation"], ["John Doe", "01/01/2017", "01/09/2017", "Vacation"]]
Другие вопросы по тегам