网站http://openbook.etoro.com/#/main/有一个实时Feed,它是由javascript通过XHR保持活动请求生成的,并通过gzip压缩的JSON字符串从服务器获取答案。
我想将Feed捕获到文件中。
通常的方式(WWW :: Mech ..)(可能)不可行,因为需要在页面中设计所有Javascripts并模拟浏览器是非常困难的任务,因此,寻找替代解决方案。
我的想法是使用中间人战术,因此broswser将完成他的工作,我希望通过perl代理捕获通信 - 专门用于此任务。
我能抓住最初的沟通,但不能抓住饲料本身。代理工作正常,因为在浏览器中,Feed只运行我的文件管理器不起作用。
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以进行所有通信。
Feed正在浏览器中运行,因此代理会向其提供数据。 (当我停止代理时,Feed也停止了)。随机(无法确定何时)我收到以下错误:
[Tue Jul 10 17:13:58 2012] (42289) ERROR: Getting request failed: Client closed
任何人都可以告诉我一个方法,如何为浏览器和keep_alive XHR服务器方面之间的所有通信构建正确的HTTP :: Proxy过滤器?
答案 0 :(得分: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
来访问要查看的任何标头。
你会注意到我将两个过滤器推到了管道上。第一个类型为HTTP::Proxy::BodyFilter::complete
,其工作是收集响应块并确保后面的实际过滤器始终在$dataref
中获得完整的消息。但是,接收和缓冲的foreach块将调用以下过滤器并传递空$dataref
。我的过滤器会通过提前返回来忽略这些。
我还设置了过滤器管道,以忽略导致JSON响应的GET请求之外的所有内容 - 因为这些似乎是最有趣的。
感谢您提出这个问题 - 这是一个有趣的小问题,您似乎已经完成了大部分的努力工作。
答案 1 :(得分:2)
设置mime
parameter,默认为仅过滤文本类型。
$proxy->push_filter(response => $hfilter, mime => 'application/json');
$proxy->push_filter(response => $bfilter, mime => 'application/json');