利用PHP的Curl扩展库可以仿照实现登录,并抓取一些须要用户账号登录往后才能查看的数据。详细实现的流程如下(个人总结):
1. 首先须要对相应的登录页面的html源代码进行剖析,得到一些必要的信息:
(1)登录页面的地址;
(2)验证码的地址;
(3)登录表单须要提交的各个字段的名称和提交办法;
(4)登录表单提交的地址;
(5)其余要须要知道要抓取的数据所在的地址。
2. 获取cookie并存储(针对利用cookie文件的网站):
$login_url = 'http://www.xxxxx'; //登录页面地址
$cookie_file = dirname(__FILE__).\公众/pic.cookie\公众; //cookie文件存放位置(自定义)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_exec($ch);
curl_close($ch);
3. 获取验证码并存储(针对利用验证码的网站):
$verify_url = \"大众http://www.xxxx\公众; //验证码地址
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $verify_url);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$verify_img = curl_exec($ch);
curl_close($ch);
$fp = fopen(\"大众./verify/verifyCode.png\"大众,'w'); //把抓取到的图片文件写入本地图片文件保存
fwrite($fp, $verify_img);
fclose($fp);
解释:由于不能实现验证码的识别,以是我这里的做法是,把验证码图片抓取下来存放到
本地文件中,然后在自己项目中的html页面中显示,让用户去填写,等用户填写
完账号、密码和验证码,并点击提交按钮之后再去进行下一步的操作。
4. 仿照提交登录表单:
$ post_url = 'http://www.xxxx'; //登录表单提交地址
$post = \"大众username=$account&password=$password&seccodeverify=$verifyCode\"大众;
//表单提交的数据(根据表单字段名和用户输入决定)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ post_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post); //提交办法为post
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_exec($ch);
curl_close($ch);
5. 抓取数据:
$data_url = \"大众http://www.xxxx\公众; //数据所在地址
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $data_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,0);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
$data = curl_exec($ch);
curl_close($ch);
到目前为止,已经把数据所在地址的这个页面都抓取下来存储在字符串变量$data中了。
须要把稳的是抓取下来的是一个网页的html源代码,也便是说这个字符串中不仅包含了你想要的数据,还包含了许多的html标签等你不想要的东西。以是如果你想要从中提取出你须要的数据的话,你还要对存放数据的页面的html代码进行剖析,然后结合字符串操作函数、正则匹配等方法从中提取出你想要的数据。
以上方法对利用http协议的一样平常网站是有效的。但是如果你要仿照登录的是利用了https协议的网站的话还须要添加如下一些处理:
1. 跳过https验证:
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
2. 利用用户代理:
$UserAgent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022; .NET CLR 1.0.3705; .NET CLR 1.1.4322)';
curl_setopt($curl, CURLOPT_USERAGENT, $UserAgent);
把稳:如果不添加这些处理的话仿照登录时是不能成功的。
利用以上程序仿照登录网站一样平常都是能成功的,但是实际上还是须要针对仿照登录的网站详细情形详细考虑。例如:有些网站编码不同,以是你抓取下来的页面是乱码的,这时就要进行一下编码转换,如:$data = iconv(\公众gb2312\"大众, \"大众utf-8\"大众,$data);,把gbk编码转换为utf8编码。还有一些对安全性哀求比较高的网站,比如网银,会把验证码放在一个内联框架中,这时你就须要先抓取到内联框架的页面然后在从中提取出验证码的地址,再去抓取验证码。还有一些网站(比如网银)是在js代码中去提交表单的,提交表单之前还会去做一些处理,比如加密等,以是如果你是直接提交的话也是不能登录成功的,你必须要去做类似的处理后再提交,但是这种情形如果你能知道js代码中进行的详细操作,比如加密的话,加密算法是若何的,你就可以进行跟它一样的处理,然后再去提交数据,这样也是能成功的。但是,关键的地方来了,如果你根本不知道它进行的是什么操作,比如它进行了加密,但是你不知道加密的详细算法,那么你就无法进行相同的操作,也就不能成功地仿照登录了。这方面范例的案例便是网银,它在js代码中提交表单之前利用网银控件对用户提交的密码和验证码进行了一些处理,但是我们根本不知道它进行的是什么操作,以是无法仿照。以是如果你以为你看了本文之后就能仿照登录网银的话那么你就太天真了,人家银行的网站能那么随意马虎被你仿照登录吗?当然,如果你能破解网银控件的话,那就另当别论了。话说回来,为什么我的感想熏染如此深刻,由于我就碰着这个难题了,不说了,说多了都是泪啊。。。