perl登录各种网站的原理与实现
perl登录各种网站的原理与实现 tkorays(tkorays@hotmail.com) 小孩子才践行大道理,大人只会讲。 ??????? 写脚本抓取某个页面内容很简单,但是往往事情没那么简单。有些页面必须是要登录才能查看的,比如你想抓取选课系统中自己的成绩?所以,下面介绍下使用perl登录网站的原理,以及实现。 原理 ??????? 如果你了解一些http原理的话,这就很好理解了。使用浏览器打开网页无非就是:你发送请求,然后服务器响应,给你所需要的页面内容。当然这些请求和相应都是有一定规律的。 ??????? 先说浏览器发送请求。 ?????? 请求常用有POST和GET两种,撇去细节不谈,两者有个很大的区别就是POST传递的参数是不显示在url中,而GET方式传递的参数会在url中显示。而我们登录有表单提交,经常要用POST和GET。比如我在开源中国搜索apache: ??????? 这个表单是GET方式的,所以url中会有参数。 ??????? 那么,是否浏览器就发送了这么多数据给服务器了呢,答案当然是,否。如上图中,点开头消息,请求头如下: ??????? 其实还发送了这些数据,所以如果你要自己用c/c++等实现,不要忘记发送必要的数据哦。(提示,每个数据使用rn分割的)如果你使用perl,有现成的库,你不需要关注太多细节的,只需要知道,可能须有cookie! ??????? 因此,请求你只需要关注,请求的参数以及可能需要的cookie。 ??????? 接下来说相应。 ??????? 同样,浏览器返回的html网页不止是你查看源代码看到的那些,还包括响应头。 ??????? 相应头和请求头差不多,主要高速浏览器该怎么处理这些相应。注意上面的Content-Type没,后面的text/html表示返回的数据是html格式的。(返回javascript时,content-type是 ??????? 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',????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?=~?/ids:s"(d+)"/g; ????$hostid?=?$1; ????$pagect?=~?/requestTokens:s'(.+)'/g; ????$requestToken?=?$1; ????$pagect?=~?/_rtks: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 ??????? 问题都解决了,你就赶快行动? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |