Лучший способ проанализировать файл со ссылками, экспортированными с Delicious.com, с помощью Nokogiri?

StackOverflow https://stackoverflow.com/questions/4477369

Вопрос

Я хочу проанализировать html-файл, содержащий ссылки, экспортированные из Delicious.Для анализа я использую Нокогири.Файл имеет следующую структуру:

<DT>
   <A HREF="http://mezzoblue.com/archives/2009/01/27/sprite_optim/"
      ADD_DATE="1233132422"
      PRIVATE="0"
      TAGS="irw_20">mezzoblue § Sprite Optimization</A>
<DT>
   <A HREF="http://datamining.typepad.com/data_mining/2008/11/minority-report-interface.html" 
      ADD_DATE="1226827542" 
      PRIVATE="0" 
      TAGS="irw_20">Minority Report Interface</A>
<DT>
   <A HREF="http://www.windowshop.com/" 
      ADD_DATE="1225267658" 
      PRIVATE="0" 
      TAGS="irw_20">Amazon Windowshop Beta</A>
<DD>Window shopping from Amazon

Как вы можете видеть, информация о ссылках находится в теге DT, а некоторые ссылки имеют комментарий в теге DD.

Чтобы получить информацию о ссылке, я делаю следующее:

doc.xpath('//dt//a').each do |node|
  title = node.text
  url = node['href']
  tags = node['tags']
  puts "#{title}, #{url}, #{tags}"
end

Мой вопрос: как мне получить информацию о ссылке И комментарий, когда присутствует тег dd?

Это было полезно?

Решение

Мой вопрос: как мне получить информацию о ссылке и комментарий, когда присутствует тег DD?

Использовать:

//DT/a | //DT[a]/following-sibling::*[1][self::DD]

Это выбирает все a элементы, имеющие DT родитель и все DD элементы, которые являются непосредственными следующими одноуровневыми элементами элемента DT элемент, который имеет a ребенок.

Примечание:Использование // настоятельно не рекомендуется, поскольку это обычно приводит к неэффективности и аномалиям в его использовании разработчиками.

Если структура XML-документа известна, избегайте использования // Сокращенное название.

Другие советы

В вашем вопросе неясно, что вы ищете.

Во-первых, HTML имеет неверный формат, поскольку <DT> теги закрыты неправильно, и в первом есть недопустимый символ a текст тега, который Ruby 1.9.2 не нравится, потому что это не UTF-8.Я преобразовал символ в объект в TextMate.

html = %{
<DT>
  <A HREF="http://mezzoblue.com/archives/2009/01/27/sprite_optim/" ADD_DATE="1233132422" PRIVATE="0" TAGS="irw_20">mezzoblue &sect; Sprite Optimization</A>
<DT>
  <A HREF="http://datamining.typepad.com/data_mining/2008/11/minority-report-interface.html" ADD_DATE="1226827542" PRIVATE="0" TAGS="irw_20">Minority Report Interface</A>
<DT>
  <A HREF="http://www.windowshop.com/" ADD_DATE="1225267658" PRIVATE="0" TAGS="irw_20">Amazon Windowshop Beta</A>
<DD>Window shopping from Amazon
}

Этот HTML-код анализируется в Нокогири после того, как он пытается это исправить:

(rdb:1) print doc.to_html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<dt>
  <a href="http://mezzoblue.com/archives/2009/01/27/sprite_optim/" add_date="1233132422" private="0" tags="irw_20">mezzoblue § Sprite Optimization</a>
<dt>
  <a href="http://datamining.typepad.com/data_mining/2008/11/minority-report-interface.html" add_date="1226827542" private="0" tags="irw_20">Minority Report Interface</a>
<dt>
  <a href="http://www.windowshop.com/" add_date="1225267658" private="0" tags="irw_20">Amazon Windowshop Beta</a>
</dt>
</dt>
</dt>
<dd>Window shopping from Amazon
</dd>
</body></html>

Обратите внимание, как закрывается dt теги группируются непосредственно перед единственным dd ярлык?Это неприятно, но ладно, потому что это не меняет того, как нам искать dd содержание.

doc = Nokogiri::HTML(html, nil, 'UTF-8')

comments = []
doc.css('dt + dd').each do |a|
  comments << a.text
end
puts comments

# >> Window shopping from Amazon

Это значит, найти <dt> с последующим <dd>.Вы не/не можете искать dt с последующим a с последующим dd потому что это не то, как анализируется HTML.Это действительно было бы dt с последующим dd, который является то, что "dt + dd" означает.

Другой способ, которым казалось, что ваш вопрос мог быть прочитан, заключался в том, что вы искали содержимое a теги:

comments = []
doc.css('a').each do |a|
  comments << a.text
end
puts comments

# >> mezzoblue § Sprite Optimization
# >> Minority Report Interface
# >> Amazon Windowshop Beta

Я предполагаю:

<DD>Window shopping from Amazon

имеет завершающий тег /DD, я не могу сказать этого по вашему фрагменту страницы.Если да, вы можете сделать:

comment = node.parent.next_sibling.next_sibling.text rescue nil

Вам нужно вызвать next_sibling дважды, потому что первый будет соответствовать (новой строке) или пробелу.Вы можете удалить все новые строки перед анализом страницы, чтобы избежать двойного вызова.Это также может быть хорошей идеей, если после тега DT есть более 1 символа новой строки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top