Der beste Weg, eine Datei mit von Delicious.com exportierten Links mit Nokogiri zu analysieren?
-
11-10-2019 - |
Frage
Ich möchte eine HTML-Datei analysieren, die aus Delicious exportierte Links enthält.Ich verwende Nokogiri zum Parsen.Die Datei hat folgenden Aufbau:
<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
Wie Sie sehen, befinden sich die Linkinformationen im DT-Tag und einige Links haben einen Kommentar im DD-Tag.
Ich gehe wie folgt vor, um die Linkinformationen zu erhalten:
doc.xpath('//dt//a').each do |node|
title = node.text
url = node['href']
tags = node['tags']
puts "#{title}, #{url}, #{tags}"
end
Meine Frage ist, wie erhalte ich die Linkinformationen UND den Kommentar, wenn ein dd-Tag vorhanden ist?
Lösung
Meine Frage ist, wie ich die Linkinformationen und den Kommentar bekomme, wenn ein DD -Tag vorhanden ist.
Verwenden:
//DT/a | //DT[a]/following-sibling::*[1][self::DD]
Dadurch werden alle ausgewählt a
Elemente, die eine haben DT
Eltern und alles DD
Elemente, die das unmittelbar folgende Geschwisterelement von a sind DT
Element, das ein hat a
Kind.
Notiz:Die Verwendung der //
Es wird dringend davon abgeraten, da es in der Regel zu Ineffizienzen und Anomalien bei der Verwendung für die Entwickler führt.
Wenn die Struktur des XML-Dokuments bekannt ist, vermeiden Sie die Verwendung von //
Abkürzung.
Andere Tipps
Aus Ihrer Frage geht nicht klar hervor, wonach Sie suchen.
Erstens ist der HTML-Code fehlerhaft, weil der <DT>
Tags werden nicht korrekt geschlossen und das erste enthält ein unzulässiges Zeichen a
Tag-Text, der Ruby 1.9.2 nicht gefällt, weil er nicht UTF-8 ist.Ich habe das Zeichen in TextMate in eine Entität umgewandelt.
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
}
Dieser HTML-Code analysiert dies in Nokogiri, nachdem versucht wurde, das Problem zu beheben:
(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>
Beachten Sie, wie der Abschluss erfolgt dt
Tags werden direkt vor dem einzigen gruppiert dd
Etikett?Das ist eklig, aber ok, denn es ändert nichts daran, wie wir danach suchen müssen dd
Inhalt.
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
Das heißt, finden <dt>
gefolgt von <dd>
.Sie können/können nicht danach suchen dt
gefolgt von a
gefolgt von dd
denn das ist nicht die Art und Weise, wie der HTML-Code analysiert wird.Das wäre es wirklich dt
gefolgt von dd
, welches ist was "dt + dd
" bedeutet.
Die andere Art und Weise, wie es schien, als ob Ihre Frage lauten könnte, war, dass Sie nach dem Inhalt der suchten a
Stichworte:
comments = []
doc.css('a').each do |a|
comments << a.text
end
puts comments
# >> mezzoblue § Sprite Optimization
# >> Minority Report Interface
# >> Amazon Windowshop Beta
Ich gehe davon aus:
<DD>Window shopping from Amazon
hat ein endendes /DD-Tag, das kann ich anhand Ihres Seitenausschnitts nicht erkennen.Wenn ja, könnten Sie Folgendes tun:
comment = node.parent.next_sibling.next_sibling.text rescue nil
Sie müssen next_sibling zweimal aufrufen, da der erste mit einem (neue Zeile) oder einem Leerzeichen übereinstimmt.Sie können alle neuen Zeilen vor dem Parsen der Seite entfernen, um den Doppelaufruf zu vermeiden.Das könnte auch eine gute Idee sein, wenn nach dem DT-Tag mehr als ein neues Zeilenzeichen steht