In einem Artikel hier kommt Nokogiri zu dem Schluss, dass er, wenn die Codierungsspezifikation "Null" ist, den Zeichensatz des Meta-Elements des ursprünglichen HTML-Codes anzeigt. Ich tat. Dieses Mal folgte ich der offiziellen Dokumentation, um zu sehen, ob die Schlussfolgerungen wirklich wahr wurden.
Offizielles Nokogiri-Dokument Dieses Mal werde ich diesem offiziellen Dokument folgen. Natürlich ist es Englisch. Normalerweise vermeide ich offizielle englische Dokumente, aber ich beschließe, sie mir anzusehen. Auch wenn Sie kein Englisch lesen können, können Sie den Code lesen. Vielleicht.
Normalerweise wird es beim Parsen mit Nokogiri als "Nokogiri :: HTML.parse (html)" geschrieben, aber offiziell scheint es die "Nokogiri :: HTML :: Document" -Klasse zu sein. Öffnen Sie das Feld Dokumentklasse, suchen Sie nach der Methode ".parse" und versuchen Sie, die Quelle mit "Quelle anzeigen" anzuzeigen.
Quelle unten
lib/nokogiri/html/document.rb
def parse string_or_io, url = nil, encoding = nil, options = XML::ParseOptions::DEFAULT_HTML
options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
# Give the options to the user
yield options if block_given?
if string_or_io.respond_to?(:encoding)
unless string_or_io.encoding.name == "ASCII-8BIT"
encoding ||= string_or_io.encoding.name
end
end
if string_or_io.respond_to?(:read)
url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
unless encoding
# Libxml2's parser has poor support for encoding
# detection. First, it does not recognize the HTML5
# style meta charset declaration. Secondly, even if it
# successfully detects an encoding hint, it does not
# re-decode or re-parse the preceding part which may be
# garbled.
#
# EncodingReader aims to perform advanced encoding
# detection beyond what Libxml2 does, and to emulate
# rewinding of a stream and make Libxml2 redo parsing
# from the start when an encoding hint is found.
string_or_io = EncodingReader.new(string_or_io)
begin
return read_io(string_or_io, url, encoding, options.to_i)
rescue EncodingFound => e
encoding = e.found_encoding
end
end
return read_io(string_or_io, url, encoding, options.to_i)
end
# read_memory pukes on empty docs
if string_or_io.nil? or string_or_io.empty?
return encoding ? new.tap { |i| i.encoding = encoding } : new
end
encoding ||= EncodingReader.detect_encoding(string_or_io)
read_memory(string_or_io, url, encoding, options.to_i)
end
Lassen Sie uns hier zuerst darauf achten
lib/nokogiri/html/document.rb
if string_or_io.respond_to?(:encoding)
unless string_or_io.encoding.name == "ASCII-8BIT"
encoding ||= string_or_io.encoding.name
end
end
string_or_io
ist eine Variable, die Sie normalerweise als HTML angeben.
Interpretation: Wenn "string_or_io" eine "Codierungs" -Methode hat, sein Codierungsname nicht "ASCII-8BIT" ist und das "Codierungs" -Argument nicht definiert ist, dann ist "Codierung" "string_or_io" Es scheint der Kodierungsname zu sein.
Das war's! Wenn Sie HTML also nicht im Binärmodus öffnen, hängt es davon ab, wie Sie HTML (Codierung) öffnen, sodass nach dem Parsen verstümmelte Zeichen auftreten können!
Was passiert also, wenn Sie die Datei im Binärmodus öffnen und das Argument "Kodierung" "Null" ist? Konzentrieren wir uns jetzt hier.
lib/nokogiri/html/document.rb
encoding ||= EncodingReader.detect_encoding(string_or_io)
Wenn das Argument "encoding" nicht definiert ist, können Sie die Methode "EncodingReader.detect_encoding" verwenden. Gehen Sie vorsichtig zur Methode "EncodingReader.detect_encoding" des Dokuments.
Zeigen Sie die Quelle wie zuvor an. Quelle unten
lib/nokogiri/html/document.rb
def self.detect_encoding(chunk)
if Nokogiri.jruby? && EncodingReader.is_jruby_without_fix?
return EncodingReader.detect_encoding_for_jruby_without_fix(chunk)
end
m = chunk.match(/\A(<\?xml[ \t\r\n]+[^>]*>)/) and
return Nokogiri.XML(m[1]).encoding
if Nokogiri.jruby?
m = chunk.match(/(<meta\s)(.*)(charset\s*=\s*([\w-]+))(.*)/i) and
return m[4]
catch(:encoding_found) {
Nokogiri::HTML::SAX::Parser.new(JumpSAXHandler.new(:encoding_found)).parse(chunk)
nil
}
else
handler = SAXHandler.new
parser = Nokogiri::HTML::SAX::PushParser.new(handler)
parser << chunk rescue Nokogiri::SyntaxError
handler.encoding
end
end
Das Methodenargument chunk
enthält diesmal string_or_io
, das heißt, was Sie normalerweise als HTML verwenden.
Es gibt viele unbekannte Methoden, daher kann ich die genaue Bedeutung nicht ermitteln. Gibt es jedoch eine Beschreibung, die sich auf den Zeichensatz von Meta im zweiten if-Block bezieht? ?? ?? Es scheint, dass der Wert von return zurückgegeben wird, und dieser Teil fühlt sich sehr verdächtig an.
Ich habe die Details der Quelle noch nicht herausgefunden, aber ich habe das Gefühl, der gesuchten Antwort näher gekommen zu sein. Wenn ich die Details der Quelle kenne, werde ich sie in einem anderen Artikel zusammenfassen.
Recommended Posts