Как извлечь текст с веб-страницы стеги, использующие Hpricot? - PullRequest
0 голосов
/ 08 декабря 2010

Я пытаюсь проанализировать HTML-файл, используя Hpricot и Ruby, но у меня возникают проблемы с извлечением «свободно плавающего» текста, который не заключен в такие теги, как <p></p>.

require 'hpricot'

text = <<SOME_TEXT
  <a href="http://www.somelink.com/foo/bar.html">Testing:</a><br />
  line 1<br />  
  line 2<br />
  line 3<br />
  line 4<br />
  line 5<br />
  <b>Here's some more text</b>
SOME_TEXT

parsed = Hpricot(text)

parsed = parsed.search('//a[@href="http://www.somelink.com/foo/bar.html"]').first.following_siblings
puts parsed

Iожидал бы, что результат будет

<br />
line 1<br />  
line 2<br />
line 3<br />
line 4<br />
line 5<br />
<b>Here's some more text</b>

Но я получаю

<br />
<br />
<br />
<br />
<br />
<br />
<b>Here's some more text</b>

Как я могу сделать Hpricot возвратной линией 1, строкой 2 и т. д.?

Ответы [ 2 ]

1 голос
/ 09 декабря 2010

Ваш первый шаг - прочитать документацию follow_siblings :

Найдите элементы одного уровня, которые следуют за текущим. Как и другие «родственные» методы, этот отсеивает узлы текста и комментариев .

Затем вы должны использовать исходный код Hpricot, чтобы обобщить, как following_siblings работает, чтобы получить что-то, что работает как following_siblings, но не отфильтровывает неконтейнерные узлы:

parsed        = Hpricot(text)
link          = parsed.search('//a[@href="http://www.somelink.com/foo/bar.html"]').first
link_sibs     = link.parent.children
what_you_want = link_sibs[link_sibs.index(link) + 1 ... link_sibs.length]

puts what_you_want

Это в значительной степени following_siblings с parent.children вместо parent.containers. Доступ к исходному коду библиотек, которые вы используете, довольно удобен, и его следует поощрять.

0 голосов
/ 09 декабря 2010

Прошло много времени с тех пор, как я использовал Hpricot, но некоторые вещи, которые я помню, могут помочь:

Быстрый способ получить весь текст:

irb(main):023:0> print parsed.inner_text
  Testing:
  line 1  
  line 2
  line 3
  line 4
  line 5
  Here's some more text

Недостатокто есть вы также получаете текст, встроенный в теги.

Аналогично, мы можем искать все 'text()' узлы:

irb(main):033:0> puts (parsed / 'text()')

Testing:

  line 1

  [...]

  line 5

Итак, мы можем сделать это:

irb(main):036:0> puts (parsed / 'text()')[2 .. -3]

  line 1

  line 2

  line 3

  line 4

  line 5

или:

irb(main):037:0> (parsed / 'text()')[2 .. -3]
=> #<Hpricot::Elements["\n  line 1", "  \n  line 2", "\n  line 3", "\n  line 4", "\n  line 5", "\n  "]>

или:

irb(main):039:0> (parsed / 'text()')[2 .. -3].map{ |t| t.inner_text.strip }
=> ["line 1", "line 2", "line 3", "line 4", "line 5", ""]

Основная идея для получения данных / текста с веб-страницы заключается в поиске ориентиров, которые можно использовать для навигации по странице.,Часто мы можем получить текст из тега <div> или <p>.Если страница не дает вам ориентиры, вы должны использовать другие приемы;Ищем последовательность текстовых узлов, за которыми следуют <br> узлы или пять строк, следующих за тегом <a> с определенным атрибутом href.Это забавно и непросто иметь дело с HTML.

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

...