5 Stimmen

Transparente Handhabung von GZip-kodierten Inhalten mit WWW::Mechanize

Ich verwende WWW::Mechanize und behandle derzeit HTTP-Antworten mit dem ' Content-Encoding: gzip Header' in meinem Code, indem ich zunächst die Antwort-Header prüfe und dann IO::Uncompress::Gunzip verwende, um den unkomprimierten Inhalt zu erhalten.

Ich möchte dies jedoch transparent tun, so dass WWW::Mechanize-Methoden wie form(), links() usw. mit dem unkomprimierten Inhalt arbeiten und diesen parsen. Da WWW::Mechanize eine Unterklasse von LWP::UserAgent ist, würde ich es vorziehen, die LWP::UA::handlers um dies zu tun.

Obwohl ich teilweise erfolgreich war (ich kann zum Beispiel den unkomprimierten Inhalt ausdrucken), bin ich nicht in der Lage, dies transparent in einer Weise zu tun, die ich aufrufen kann

$mech->forms();

Zusammengefasst: Wie "ersetze" ich den Inhalt innerhalb des $mech-Objekts, so dass von diesem Punkt an alle WWW::Mechanize-Methoden so funktionieren, als wäre die Content-Encoding nie geschehen?

Ich würde mich über Ihre Aufmerksamkeit und Hilfe freuen. Danke

8voto

Fayland Lam Punkte 1018

0 Stimmen

Danke! Ich frage mich, wie ich das übersehen konnte - ich habe CPAN durchsucht :)

3voto

jettero Punkte 805

Es sieht für mich so aus, als könnten Sie es durch das Element $res->content( $bytes ) ersetzen.

Übrigens habe ich diese Dinge gefunden, indem ich mir den Quelltext von LWP::UserAgent, dann HTTP::Response, dann HTTP::Nachricht .

0 Stimmen

Ja - es funktioniert. Danke. Ich werde es verwenden, wenn ich mehr als nur gunzip-Inhalte machen will. Für jetzt werde ich nur das von Fayland vorgeschlagene Modul verwenden

0 Stimmen

Seien Sie vorsichtig, WWW::Mechanize::GZip scheint ziemlich fehlerhaft zu sein (siehe stackoverflow.com/questions/6874076/ ). Leider verstehe ich die Ersetzungsmethode, von der Sie sprechen, nicht ganz: Können Sie bitte einen Beispielcode angeben?

0 Stimmen

@jettero: Meinten Sie "$res->decoded_content()"? Auf jeden Fall habe ich deine Antwort hochgestimmt, weil ich gar nicht daran gedacht habe, das zu überprüfen. Ich habe es gefunden, als ich nach "Encoding" gesucht habe in perldoc HTTP::Antwort . Danke!

0voto

user2695439 Punkte 11

Sie ist in UserAgent und damit in Mechanize integriert. Ein WICHTIGER Vorbehalt um Ihnen einige Haare zu ersparen

-Zum Debuggen sollten Sie nach Fehlern suchen $@ nach dem Aufruf von decoded_content.

$html = $r->decoded_content;
die $@ if $@;

Noch besser ist es, den Quellcode von HTTP::Message zu durchsuchen und sicherzustellen, dass alle Unterstützungspakete vorhanden sind

In meinem Fall gab decoded_content undef zurück, obwohl content raw binary ist, und ich habe mich auf die Suche gemacht. UserAgent setzt das Fehlerflag, wenn die Dekodierung fehlschlägt, aber Mechanize ignoriert es einfach (es prüft oder protokolliert das Vorkommen nicht als eigenen Fehler/Warnung).

In meinem Fall sagt $@: "Can't find IO/HTML.pm It was eval'ed

Nachdem ich mich in die Quelle vertieft habe, finde ich heraus, dass der eingebaute Entschlüsselungsprozess lang, akribisch und mühsam ist und so ziemlich jedes Szenario abdeckt und viele Vermutungen zulässt (Danke, Gisle!).

wenn Sie paranoid sind, setzen Sie explizit den Standard-Header, der bei jeder Anfrage bei new() verwendet werden soll

    $browser = new WWW::Mechanize('default_headers' => HTTP::Headers->new('Accept-Encoding' 
                            => scalar HTTP::Message::decodable()));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X