6

サイトhttp://openbook.etoro.com/#/main/には、XHRキープアライブリクエストを介してjavascriptによって生成され、gzip圧縮されたJSON文字列としてサーバーから回答を取得するライブフィードがあります。

フィードをファイルにキャプチャしたい。

通常の方法(WWW :: Mech ..)は(おそらく)実行可能ではありません。ページ内のすべてのJavascriptをリバースエンジニアリングし、ブラウザーをシミュレートする必要があるため、別の解決策を探す必要があります。

私のアイデアは中間者攻撃を使用しているので、ブラウザが彼の仕事をし、perlプロキシを介して通信をキャプチャしたいと思います-このタスク専用です。

最初の通信はキャッチできますが、フィード自体はキャッチできません。ブラウザではフィードが実行されているので、プロキシは正常に機能しています。ファイラーだけが機能していません。

use HTTP::Proxy;
use HTTP::Proxy::HeaderFilter::simple;
use HTTP::Proxy::BodyFilter::simple;
use Data::Dumper;
use strict;
use warnings;

my $proxy = HTTP::Proxy->new(
     port => 3128, max_clients => 100, max_keep_alive_requests => 100
);

my $hfilter = HTTP::Proxy::HeaderFilter::simple->new(
    sub {
        my ( $self, $headers, $message ) = @_;
        print STDERR "headers", Dumper($headers);
    }
);

my $bfilter = HTTP::Proxy::BodyFilter::simple->new(
    filter => sub {
        my ( $self, $dataref, $message, $protocol, $buffer ) = @_;
        print STDERR "dataref", Dumper($dataref);
    }
);

$proxy->push_filter( response => $hfilter); #header dumper
$proxy->push_filter( response => $bfilter); #body dumper
$proxy->start;

Firefoxは、すべての通信に上記のプロキシを使用して構成されています。

フィードはブラウザで実行されているため、プロキシがデータをフィードします。(プロキシを停止すると、フィードも停止します)。ランダムに(いつわかりません)次のエラーが発生します:

[Tue Jul 10 17:13:58 2012] (42289) ERROR: Getting request failed: Client closed

誰かが私に方法を教えてもらえますか、Dumper用の正しいHTTP :: Proxyフィルターを構築する方法、ブラウザとサーバー間のすべての通信はkeep_alive XHRに関係しますか?

4

2 に答える 2

5

これがあなたが求めていることをしていると私が思うことです:

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;

use HTTP::Proxy;
use HTTP::Proxy::BodyFilter::complete;
use HTTP::Proxy::BodyFilter::simple;
use JSON::XS     qw( decode_json );
use Data::Dumper qw( Dumper );

my $proxy = HTTP::Proxy->new(
    port                     => 3128,
    max_clients              => 100,
    max_keep_alive_requests  => 100,
);

my $filter = HTTP::Proxy::BodyFilter::simple->new(
    sub {
        my ( $self, $dataref, $message, $protocol, $buffer ) = @_;
        return unless $$dataref;
        my $content_type = $message->headers->content_type or return;
        say "\nContent-type: $content_type";
        my $data = decode_json( $$dataref );
        say Dumper( $data );
    }
);

$proxy->push_filter(
    method   => 'GET',
    mime     => 'application/json',
    response => HTTP::Proxy::BodyFilter::complete->new,
    response => $filter
);

$proxy->start;

$message->headersボディフィルターで使用することを確認したいヘッダーにアクセスできるため、個別のヘッダーフィルターは必要ないと思います。

2つのフィルターをパイプラインにプッシュしたことに気付くでしょう。最初のものはタイプHTTP::Proxy::BodyFilter::completeであり、その仕事は応答のチャンクを収集し、後続の実際のフィルターが常にで完全なメッセージを取得するようにすること$datarefです。ただし、受信およびバッファリングされたチャンクごとに、次のフィルターが呼び出され、空のが渡されます$dataref。私のフィルターは早く戻ることでこれらを無視します。

また、JSON応答を生成するGETリクエストを除くすべてを無視するようにフィルターパイプラインを設定しました-これらが最も興味深いと思われるためです。

この質問をしてくれてありがとう-それは興味深い小さな問題でした、そしてあなたはすでにほとんどの大変な仕事をしたようでした。

于 2012-07-11T09:46:01.397 に答える
2

mimeパラメータを設定します。デフォルトでは、テキストタイプのみをフィルタリングします。

$proxy->push_filter(response => $hfilter, mime => 'application/json');
$proxy->push_filter(response => $bfilter, mime => 'application/json');
于 2012-07-11T09:05:24.453 に答える