fakelogin.php//模拟post提交
$url='http://www.xxxxx.com/member/login.php'; //表单的action处理程序 unset($post_data); $post_data['username'] = "name"; //帐号 $post_data['password'] = "pass"; //密码 $post_data['type'] = "xxx"; //登录表单的其他域内容..下略 $post_data['formAction'] = "user_login"; $o=""; //组织post数据 foreach ($post_data as $k=>$v) $o.= "$k=".urlencode($v)."&"; $o=substr($o,0,-1); //去掉最后一个& $ch = curl_init(); //curl对象 curl_setopt($ch, CURLOPT_POST, 1); //method post curl_setopt($ch, CURLOPT_POSTFIELDS, $o);//post的数据 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回的html源码(1表示输出,0表示不输出) curl_setopt($ch, CURLOPT_HEADER, 1); //返回内容包含header curl_setopt($ch, CURLOPT_URL,$url); //提交地址 curl_setopt($ch, CURLOPT_COOKIEJAR, 'E:/webroot/f/cookie.txt'); //保存cookie $result = curl_exec($ch); //提交登录获取登录结果 file_put_contents("logined.txt",$result); //debug_ 把结果保存到文件查看
至此 http://www.xxxx.com 的登录ok了
之后访问 x网站只需要
readdata.php
$url = "http://www.xxxxx.com/content/.../"; //要抓取源码的URL
$ch = curl_init(); //curl对象 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回的html源码(1表示输出,0表示不输出) curl_setopt($ch, CURLOPT_HEADER, 0); //返回内容: 1 包含header; 0 不包含 curl_setopt($ch, CURLOPT_URL,$url); //要抓取源码 curl_setopt($ch, CURLOPT_COOKIEFILE,'E:/webroot/f/cookie.txt'); // 读取已储存的Cookie信息 $result = curl_exec($ch); $result = iconv("GBK","UTF-8//IGNORE",$result); //网站原本是gbk编码,转换成utf-8便于之后处理 file_put_contents("data.txt",$result); //debug 把源码保存到文件
接着有点棘手的是其实要抓取的内容在 www.yyyy.com 网站
而 x网站和y网站之间的登录是怎么整合的呢?
用户在浏览器的操作方式是 x网站登陆成功,点某个跳转的link -> 去到y网站
http://www.xxxxx.com/go.php?no=eW91cnVzZXJuYW1l
后面"no"参数用base64 decode 之后发现是用户名
如果直接用浏览器打开这个link的话发现是不能登录的,就是说服务器端用了session或cookies的方式做校验
尝试获取这条link ,继续在上面的 readdata.php 代码修改
$url = "http://www.xxxxx.com/go.php?no=eW91cnVzZXJuYW1l"; $ch = curl_init(); //curl对象 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回的html源码(1表示输出,0表示不输出) curl_setopt($ch, CURLOPT_HEADER, 0); //返回内容: 1 包含header; 0 不包含 curl_setopt($ch, CURLOPT_URL,$url); //要抓取源码 curl_setopt($ch, CURLOPT_COOKIEFILE,'E:/webroot/f/cookie.txt'); // 读取已储存的Cookie信息 $result = curl_exec($ch); $result = iconv("GBK","UTF-8//IGNORE",$result); //网站原本是gbk编码,转换成utf-8便于之后处理 file_put_contents("data.txt",$result); //debug 把源码保存到文件
再看 data.txt 空白,什么也没有,但浏览器来操作的话这步会自动跳转到y网站,猜测是在 header 做了 location 跳转
将上述代码改动一行
curl_setopt($ch, CURLOPT_HEADER, 1);
运行后查看data.txt 内容:
HTTP/1.1 302 Found Date: Tue, 20 Mar 2012 05:03:40 GMT Server: Apache/2.0.52 (Red Hat) X-Powered-By: PHP/4.3.9 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Location: http://www.yyyy.com/gzindex.asp?sessionid=i44hi1hh1ih11d1..n1hi1h.1hi.h.ntd8u18it8i14nui8i4t8ii48uin&id=yourusername Content-Length: 0 Connection: close Content-Type: text/html;charset=gb2312
果然如所料,找到之后就好办了。
连接附带编码了的sessionid和 用户名id 就是这串地址实现了y网站的登录
在readdata.php 追加处理
//...以上内容略,接上一段源码 //获取header location 新地址 $newurl = strstr($result,"http://"); $newurl = substr($newurl,0,strpos($newdomain,"\n")-1); curl_setopt($ch, CURLOPT_COOKIEJAR, 'E:/webroot/f/cookie2.txt'); //把y站的cookies保存到 cookies2.txt,不过连着以上代码的话,其实这份cookies同时包含了 x站和y站的cookies信息 curl_setopt($ch, CURLOPT_URL,$newurl); //登录y站 $result = curl_exec($ch); //获取登录y站的结果,和cookies
大功告成,之后访问y站时只需要
curl_setopt($ch, CURLOPT_COOKIEFILE,'E:/webroot/f/cookie2.txt'); 就能以已登录的身份获取信息.
要模拟一键登录,将 fakelogin.php 和readdata.php 两文件的代码合并在一起就可以直接完成 x网站登录,跳转到y站同时登录。
只要在cookies和session未超时的一段时间内,怎样操作悉随尊便.
*备忘:如果 curl_setopt 的 CURLOPT_RETURNTRANSFER 变量 0 的话,就不会返回源码,能节省传入的流量,只返回单个字符"1".