Лучший способ проанализировать файл со ссылками, экспортированными из Delicious.com с помощью Nokogiri?
Я хочу проанализировать HTML-файл, содержащий ссылки, экспортированные из Delicious. Я использую Nokogiri для разбора. Файл имеет следующую структуру:
<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?
3 ответа
Мой вопрос: как мне получить информацию о ссылке и комментарий, когда присутствует тэг 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 § 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 анализирует это в Nokogiri после того, как пытается это исправить:
(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 дважды, потому что первый из них будет соответствовать \n (новая строка) или пробелу. Вы можете удалить все новые строки перед анализом страницы, чтобы избежать двойного вызова. Это также может быть хорошей идеей, если после тэга DT более 1 символа новой строки