Le "inférieur à" (<) isn't legal HTML, mais les navigateurs ont beaucoup de code pour comprendre ce que l'on entend par le HTML au lieu de simplement afficher une erreur. C'est pourquoi votre exemple HTML incorrect affiche la façon dont vous le souhaitez dans les navigateurs. Donc, l'astuce consiste à s'assurer que Nokogiri fait le même travail pour compenser le mauvais code HTML. Assurez-vous d'analyser le fichier HTML au lieu de XML:
f = File.open("table.html")
doc = Nokogiri::HTML(f)
Ce fichier parse très bien, mais jette le texte < 1 g
. Regardez comment le contenu des 2 premiers éléments de TD est analysé:
doc.xpath('(//td)[1]/text()').to_s
=> "\n "
doc.xpath('(//td)[2]/text()').to_s
=> "0 %"
Nokogiri a jeté votre texte invalide, mais a gardé l'analyse de la structure environnante. Vous pouvez même le message d'erreur de Nokogiri:
doc.errors
=> [#<Nokogiri::XML::SyntaxError: htmlParseStartTag: invalid element name>]
doc.errors[0].line
=> 3
Eh oui, la ligne 3 est mauvais. Il semble donc que Nokogiri n'a pas le même niveau de support pour l'analyse syntaxique de HTML invalide que les navigateurs. Je recommande d'utiliser une autre bibliothèque pour prétraiter vos fichiers. J'ai essayé de courir TagSoup sur votre fichier d'exemple et elle a fixé le <
en changeant à <
comme ceci:
% java -jar tagsoup-1.1.3.jar foo.html | xmllint --format -
src: foo.html
<?xml version="1.0" standalone="yes"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<table>
<tbody>
<tr>
<th colspan="1" rowspan="1">Total Weight</th>
<td colspan="1" rowspan="1"><1 g</td>
<td colspan="1" rowspan="1" style="text-align: right">0 %</td>
</tr>
<tr>
<td colspan="3" rowspan="1" class="skinny_black_bar"/>
</tr>
</tbody>
</table>
</body>
</html>
Y a-t-il des paquets Ruby qui analysent HTML aussi fermement que TagSoup? – sampablokuper