La meilleure façon d'analyser un fichier avec des liens exportés depuis Delicious.com à l'aide de Nokogiri ?
-
11-10-2019 - |
Question
Je souhaite analyser un fichier HTML contenant des liens exportés depuis Delicious.J'utilise Nokogiri pour l'analyse.Le fichier a la structure suivante :
<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
Comme vous pouvez le voir, les informations sur le lien se trouvent dans la balise DT et certains liens ont un commentaire dans une balise DD.
Je fais ce qui suit pour obtenir les informations sur le lien :
doc.xpath('//dt//a').each do |node|
title = node.text
url = node['href']
tags = node['tags']
puts "#{title}, #{url}, #{tags}"
end
Ma question est de savoir comment obtenir les informations sur le lien ET le commentaire lorsqu'une balise dd est présente ?
La solution
Ma question est de savoir comment obtenir les informations du lien et le commentaire lorsqu'une balise DD est présente?
Utiliser:
//DT/a | //DT[a]/following-sibling::*[1][self::DD]
Ceci sélectionne tout a
éléments qui ont un DT
parent et tout DD
éléments qui sont l'élément frère immédiatement suivant d'un DT
élément qui a un a
enfant.
Note:L'utilisation du //
est fortement déconseillé car il entraîne généralement des inefficacités et des anomalies dans son utilisation pour les développeurs.
Chaque fois que la structure du document XML est connue, évitez d'utiliser le //
abréviation.
Autres conseils
Votre question n'est pas claire sur ce que vous recherchez.
Premièrement, le HTML est mal formé car le <DT>
les balises ne sont pas fermées correctement et il y a un caractère illégal dans la première a
le texte de la balise que Ruby 1.9.2 n'aime pas car ce n'est pas UTF-8.J'ai converti le personnage en entité dans 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
}
Ce HTML analyse ceci dans Nokogiri après avoir essayé de le réparer :
(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>
Remarquez comment la clôture dt
les balises sont regroupées juste avant le seul dd
étiqueter?C'est dégueulasse, mais ok parce que ça ne change pas la façon dont nous devons rechercher le dd
contenu.
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
Cela signifie, trouvez <dt>
suivi de <dd>
.Vous ne/ne pouvez pas chercher dt
suivi de a
suivi de dd
parce que ce n'est pas ainsi que le HTML analyse.Ce serait vraiment dt
suivi de dd
, lequel est quoi "dt + dd
" moyens.
L'autre façon dont votre question semblait se lire était que vous recherchiez le contenu du a
Mots clés:
comments = []
doc.css('a').each do |a|
comments << a.text
end
puts comments
# >> mezzoblue § Sprite Optimization
# >> Minority Report Interface
# >> Amazon Windowshop Beta
Je suppose que :
<DD>Window shopping from Amazon
a une balise de fin /DD, je ne peux pas le dire à partir de votre extrait de page.Si c'est le cas, tu pourrais faire :
comment = node.parent.next_sibling.next_sibling.text rescue nil
Vous devez appeler next_sibling deux fois car le premier correspondra à un (nouvelle ligne) ou à un espace.Vous pouvez supprimer toutes les nouvelles lignes avant d'analyser la page pour éviter le double appel.Cela pourrait également être une bonne idée s'il y a plus d'un caractère de nouvelle ligne après la balise DT.