perl的LWP是抓取網頁的經典模塊,學習的過程中用這個模塊寫了一個小程序,是通過抓取有道翻譯的翻譯結果來實現的。廢話不多說,先貼代碼(解釋見下文
#! /usr/bin/perl #學習perl LWP時用post做的翻譯小腳本 #調用的是有道詞典 use strict; use warnings; use LWP::UserAgent; use JSON ; #use Data::Dumper; my $browser = LWP::UserAgent->new(); print "Please input the word:"; chomp (my $input = <STDIN>); my $response = $browser->post( # 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=https://www.google.com.hk/', 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null', [ 'type' => 'AUTO', 'i' => "$input", 'doctype' => 'json', ], ); if($response->is_success){ my $result = $response->content; my $json = new JSON; my $obj = $json->decode($result); #print Dumper $obj; my $trans = @{$obj->{'translateResult'}[0]}[0]->{"tgt"}; $trans = "翻譯結果:$trans" if $trans; my $string; eval{ $string = join " ", @{$obj->{'smartResult'}->{"entries"}}; }; $trans = "$trans\n其他結果:$string" if $string; print $trans."\n" // "Not found\n"; }
LWP實現表單POST提交
在chrome下打開有道翻譯,然后在打開審查元素功能,試着輸入hello,然后使用自動翻譯,就可以捕獲到下列的POST請求。
我們使用LWP::UserAgent模塊來模仿瀏覽器實現的POST功能。LWP的經典教程可以在這里學習。
需要調用的函數為 $browser->post(url, pairs_arrayref),其中,pairs_arrayref為提交的參數,在這里我們根據Form Data里的信息就可以得出參數列表,我們這里的列表選擇的是i代表提交的需翻譯的單詞,type是自動翻譯,doctype 指的是返回的數據為json數據
my $response = $browser->post( # 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=https://www.google.com.hk/', 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null', [ 'type' => 'AUTO', 'i' => "$input", 'doctype' => 'json', ], );
解析JSON
返回的JSON如下
{"type":"ZH_CN2EN","errorCode":0,"elapsedTime":10,"translateResult":[[{"src":"你好","tgt":"How are you"}]],"smartResult":{"type":1,"entries":["","hello;hi"]}}
其中translateResult是翻譯結果,smartResult是其它結果。
我們使用的是perl的JSON模塊來對json數據進行解析(JSON模塊的文檔見這里)
my $result = $response->content; my $json = new JSON; my $obj = $json->decode($result);
使用decode將json數據轉化成了perl的數據,返回的是對象的引用。
為了方便,我們可以將其用Dumper將對象打印出來看內部的結構(Data::Dumper的文檔在這里)
print Dumper $obj
這是翻譯“你好”的時候顯示的結果(終端下中文有點亂碼..):
$VAR1 = { 'smartResult' => { 'entries' => [ '', "hello\x{ef}\x{bc}\x{9b}hi" ], 'type' => 1 }, 'errorCode' => 0, 'translateResult' => [ [ { 'tgt' => 'How are you', 'src' => "\x{e4}\x{bd}\x{a0}\x{e5}\x{a5}\x{bd}" } ] ], 'type' => 'ZH_CN2EN', 'elapsedTime' => 10 };
可以看出整個$obj是一個匿名哈希引用,而其中smartResult也是一個匿名哈希引用,translateResult則是一個匿名數組引用,然后一層層下去,最終鍵src的的值為翻譯結果(關於perl的引用可以看我的另外一篇博文)於是,我們可以用下列方式提取翻譯結果。
my $trans = @{$obj->{'translateResult'}[0]}[0]->{"tgt"}; #最終翻譯結果 @{$obj->{'smartResult'}->{"entries"}}; #其他智能翻譯結果
最后運行截圖: