Прозрачная работа с GZip-кодированным содержимым с помощью WWW :: Mechanize - PullRequest
5 голосов
/ 17 мая 2009

Я использую WWW :: Mechanize и в настоящее время обрабатываю ответы HTTP с заголовком 'Content-Encoding: gzip' в своем коде, сначала проверив заголовки ответов, а затем используя IO :: Uncompress :: Gunzip, чтобы получить несжатый контент.

Однако я хотел бы сделать это прозрачно, чтобы методы WWW :: Mechanize, такие как form (), links () и т. Д., Работали и анализировали несжатый контент. Поскольку WWW :: Mechanize является подклассом LWP :: UserAgent, я бы предпочел использовать для этого LWP :: UA :: handlers .

Хотя я частично добился успеха (например, я могу распечатать несжатый контент), я не могу сделать это прозрачным способом, которым я могу позвонить

$mech->forms();

В итоге: как мне "заменить" содержимое внутри объекта $ mech, чтобы с этого момента все методы WWW :: Mechanize работали так, как если бы кодирование содержимого никогда не происходило?

Буду признателен за ваше внимание и помощь. Спасибо

Ответы [ 3 ]

8 голосов
/ 17 мая 2009
3 голосов
/ 17 мая 2009

Мне кажется, вы можете заменить его, используя член $ res-> content ($ bytes).

Кстати, я нашел этот материал, посмотрев на источник LWP :: UserAgent, затем HTTP :: Response, затем HTTP :: Message .

0 голосов
/ 05 сентября 2013

Он встроен в UserAgent и, таким образом, Mechanize. Одна ОСНОВНАЯ оговорка , чтобы сэкономить волосы

-Для отладки убедитесь, что вы проверили ошибку $ @ после вызова decoded_content.

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

Еще лучше, посмотрите источник HTTP :: Message и убедитесь, что все пакеты поддержки есть

В моем случае decoded_content возвратил undef, а содержимое - двоичный файл, и я продолжил погоню. UserAgent установит флаг ошибки при неудачном декодировании, но Mechanize просто проигнорирует его (он не проверяет и не регистрирует частоту как свою собственную ошибку / предупреждение).

В моем случае $ @ sez: "Не могу найти IO / HTML.pm .. Это было оценено

После того, как я погрузился в источник, я обнаружил, что встроенный процесс декодирования является долгим, дотошным и трудным, охватывает практически каждый сценарий и дает массу догадок (спасибо, Жизель!)

если вы параноик, явно установите заголовок по умолчанию, который будет использоваться с каждым запросом в new ()

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