¿La mejor manera de analizar un archivo con enlaces exportados desde Delicious.com usando Nokogiri?

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

Pregunta

Quiero analizar un archivo html que contiene enlaces exportados desde Delicious.Estoy usando Nokogiri para el análisis.El archivo tiene la siguiente estructura:

<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

Como puede ver, la información del enlace está en la etiqueta DT y algunos enlaces tienen un comentario en una etiqueta DD.

Hago lo siguiente para obtener la información del enlace:

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

Mi pregunta es ¿cómo obtengo la información del enlace Y el comentario cuando hay una etiqueta dd presente?

¿Fue útil?

Solución

Mi pregunta es ¿cómo obtengo la información del enlace y el comentario cuando una etiqueta DD está presente?

Usar:

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

Esto selecciona todo a elementos que tienen un DT padre y todo DD elementos que son el elemento hermano inmediatamente siguiente de un DT elemento que tiene un a niño.

Nota:El uso de la // Se desaconseja enfáticamente porque generalmente genera ineficiencias y anomalías en su uso para los desarrolladores.

Siempre que se conozca la estructura del documento XML, evite utilizar el // abreviatura.

Otros consejos

Tu pregunta no es clara sobre lo que estás buscando.

Primero, el HTML tiene un formato incorrecto porque el <DT> Las etiquetas no están cerradas correctamente y hay un carácter ilegal en la primera. a Texto de la etiqueta que a Ruby 1.9.2 no le gusta porque no es UTF-8.Convertí el personaje en una entidad en 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
}

Ese HTML analiza esto en Nokogiri después de intentar arreglarlo:

(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>

Observe cómo el cierre dt Las etiquetas se agrupan justo antes de la única. dd ¿etiqueta?Eso es repugnante, pero está bien porque no cambia la forma en que tenemos que buscar el dd contenido.

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

Eso significa encontrar <dt> seguido por <dd>.No puedes/no puedes buscar dt seguido por a seguido por dd porque así no es como analiza el HTML.realmente seria dt seguido por dd, Que es que "dt + dd" medio.

La otra forma en que parecía que se podía leer tu pregunta era que estabas buscando el contenido del a etiquetas:

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

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

Supongo que:

<DD>Window shopping from Amazon

tiene una etiqueta final /DD, no puedo saberlo solo con el fragmento de la página.Si es así, podrías hacer:

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

Debes llamar a next_sibling dos veces porque la primera coincidirá con un (nueva línea) o un espacio en blanco.Puede eliminar todas las líneas nuevas antes de analizar la página para evitar la doble llamada.También podría ser una buena idea en caso de que haya más de un carácter de nueva línea después de la etiqueta DT.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top