perl登陸各類網站的原理與實現

perl登陸各類網站的原理與實現javascript

tkorays(tkorays@hotmail.com)html

小孩子才踐行大道理,大人只會講。java


        寫腳本抓取某個頁面內容很簡單,可是每每事情沒那麼簡單。有些頁面必須是要登陸才能查看的,好比你想抓取選課系統中本身的成績?因此,下面介紹下使用perl登陸網站的原理,以及實現。c++


原理shell

        若是你瞭解一些http原理的話,這就很好理解了。使用瀏覽器打開網頁無非就是:你發送請求,而後服務器響應,給你所須要的頁面內容。固然這些請求和相應都是有必定規律的。apache

        先說瀏覽器發送請求瀏覽器

       請求經常使用有POST和GET兩種,撇去細節不談,二者有個很大的區別就是POST傳遞的參數是不顯示在url中,而GET方式傳遞的參數會在url中顯示。而咱們登陸有表單提交,常常要用POST和GET。好比我在開源中國搜索apache:服務器

        這個表單是GET方式的,因此url中會有參數。cookie

        那麼,是否瀏覽器就發送了這麼多數據給服務器了呢,答案固然是,否。如上圖中,點開頭消息,請求頭以下:併發

        其實還發送了這些數據,因此若是你要本身用c/c++等實現,不要忘記發送必要的數據哦。(提示,每一個數據使用\r\n分割的)若是你使用perl,有現成的庫,你不須要關注太多細節的,只須要知道,可能須有cookie!

        所以,請求你只須要關注,請求的參數以及可能須要的cookie。

        接下來講相應

        一樣,瀏覽器返回的html網頁不止是你查看源代碼看到的那些,還包括響應頭。

        相應頭和請求頭差很少,主要高速瀏覽器該怎麼處理這些相應。注意上面的Content-Type沒,後面的text/html表示返回的數據是html格式的。(返回javascript時,content-type是application/x-javascript)。固然並非全部的相應都有響應頭,並且大多時候,你也不須要關注它。這裏我只是湊字數說說,徹底能夠忽略。返回的頁面,你徹底只須要獲取頭後面的東西(反正你也知道返回的是html仍是javascript,何須還判斷呢)。

        cookies是保存在瀏覽器端的一些小數據,能夠用於保存一些信息。它其實就是一些鍵值對。不少時候,服務器會生成一些數據給瀏覽器,這些在以後的通訊過程當中是很重要的。所幸的是,perl有現成的庫供咱們管理cookies,若是你要一步步實現,就頭大了。

        對了,還要注意的是url編碼問題,有時候會出現。

實現

        說了原理固然要說實現了,否則我就是欺騙讀者的感情了。

        perl中使用到的主要包有LWP,會用到它的UserAgent、Cookies、Response等類。這些類有不明白的地方能夠查看cpan。

        這裏咱們須要模擬一個瀏覽器的行爲,因此要建立一個UserAgent對象。

my $ua = LWP::UserAgent->new;
$ua->agent("Mozilla/5.0 (Windows NT 6.1; rv:30.0) Gecko/20100101 Firefox/30.0");

        這樣,請求頭裏面的瀏覽器就變成了火狐,服務器會覺得咱們是使用火狐呢。

        不能忘記cookies哦。

my $cookie_jar = HTTP::Cookies->new(
    file=>'lwp_cookies.txt',
    autosave=>1,
    ignore_discard=>1);
$ua->cookie_jar($cookie_jar);

        以後調用UserAgent的post和get方法,想幹什麼就幹甚麼。

        若是你看的不是很明白,下面給出一個登陸人人併發狀態的例子,好好領悟吧。有註釋哦:

#!/usr/bin/perl
# Copyright 2014 tkorays. All rights reserved.
# author tkorays
# email tkorays@hotmail.com
use strict;
use warnings;
use LWP;
use LWP::Simple;
use LWP::UserAgent;
use HTTP::Cookies;
use HTTP::Headers;
use HTTP::Response;
use Encode;
use URI::Escape;
use URI::URL;

my $email = '***@**.com';
my $password = '***';
my $domain = 'renren.com';
my $hostid='';
my $requestToken='';
my $rtk='';
my $channel='renren';

my $ua = LWP::UserAgent->new;
$ua->agent("Mozilla/5.0 (Windows NT 6.1; rv:30.0) Gecko/20100101 Firefox/30.0");
my $cookie_jar = HTTP::Cookies->new(
    file=>'lwp_cookies.txt',
    autosave=>1,
    ignore_discard=>1);
$ua->cookie_jar($cookie_jar);

my $login_url = 'http://www.renren.com/PLogin.do';

# 這裏面沒有判斷是否須要驗證碼,聰明的你學完後確定知道怎麼搞定的
# 人人是post登錄的,第一個參數是登錄的地址,第二個參數是一個匿名hash
my $res = $ua->post($login_url,{
        'email'=>$email,
        'password'=>$password,
        'domain'=>$domain});
my $homepage; 
# 判斷響應頭裏面的location,肯定是否登錄成功   
if($res->header('Location') eq 'http://www.renren.com/Home.do'){
    print 'login ok...',"\n";
    $homepage = $ua->get('http://www.renren.com/home'); 
}else{
    exit;
}
# 做爲福利,下面仍是貼上,髮狀態的吧,後面就不註釋了
#####################################
if($homepage->is_success){
    my $pagect = $homepage->content;
    $pagect =~ /id\s:\s"(\d+)"/g;
    $hostid = $1;
    $pagect =~ /requestToken\s:\s'(.+)'/g;
    $requestToken = $1;
    $pagect =~ /_rtk\s:\s'(.+)'/;
    $rtk = $1;
    
            
}else{
    exit;    
}
my $purl = 'http://shell.renren.com/'.$hostid.'/status';
my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime(); 
$year +=1900;
$mon++;
my $postret = $ua->post($purl,{
    'content'=>"renren test,by perl script,author:tkorays,date:$year-$mon-$day $hour:$min:$sec.",
    'hostid'=>$hostid,
    'requestToken'=>$requestToken,
    '_rtk'=>$rtk,
    'channel'=>$channel});
if($postret->is_success){
    print 'send ok...',"\n";
}else{
    print 'fuck!';
}

       

        有驗證碼怎麼辦?UserAgent的get、方法獲取啊。

        給個簡單的例子吧:

my $res = $ua->get($url.'/GenImg');
    if(!$res->is_success){
        return 0;
    }
    open(FILE_HANDLE,'>img.jpg');
    binmode FILE_HANDLE;
    print FILE_HANDLE $res->content;
    close FILE_HANDLE;

        上面的代碼把驗證碼存爲圖片。因此驗證碼問題就解決了。

GO

        問題都解決了,你就趕快行動?

相關文章
相關標籤/搜索