PHP使用Curl实现模拟登录及抓取数据功能示例


Posted in PHP onApril 27, 2018

本文实例讲述了PHP使用Curl实现模拟登录及抓取数据功能。分享给大家供大家参考,具体如下:

使用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代码中提交表单之前使用网银控件对用户提交的密码和验证码进行了一些处理,但是我们根本不知道它进行的是什么操作,所以无法模拟。所以如果你以为你看了本文之后就能模拟登录网银的话那么你就太天真了,人家银行的网站能那么容易被你模拟登录吗?当然,如果你能破解网银控件的话,那就另当别论了。话说回来,为什么我的感受如此深刻,因为我就遇到这个难题了,不说了,说多了都是泪啊。。。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP写杨辉三角实例代码
Jul 17 PHP
PHP面向对象学习笔记之二 生成对象的设计模式
Oct 06 PHP
PHP把JPEG图片转换成Progressive JPEG的方法
Jun 30 PHP
从零开始学YII2框架(五)快速生成代码工具 Gii 的使用
Aug 20 PHP
php中mt_rand()随机数函数用法
Nov 24 PHP
php利用smtp类实现电子邮件发送
Oct 30 PHP
PHP获取不了React Native Fecth参数的解决办法
Aug 26 PHP
浅析php中array_map和array_walk的使用对比
Nov 20 PHP
PHP实现向关联数组指定的Key之前插入元素的方法
Jun 06 PHP
PHP实现的装箱算法示例
Jun 23 PHP
php 实现简单的登录功能示例【基于thinkPHP框架】
Dec 02 PHP
thinkphp5实现微信扫码支付
Dec 23 PHP
PHP获取文件扩展名的常用方法小结【五种方式】
Apr 27 #PHP
PHP四种排序算法实现及效率分析【冒泡排序,插入排序,选择排序和快速排序】
Apr 27 #PHP
php-fpm服务启动脚本的方法
Apr 27 #PHP
php-fpm添加service服务的例子
Apr 27 #PHP
laravel 5.4 + vue + vux + element的环境搭配过程介绍
Apr 26 #PHP
PHP分享图片的生成方法
Apr 25 #PHP
PHP receiveMail实现收邮件功能
Apr 25 #PHP
You might like
比较详细PHP生成静态页面教程
2012/01/10 PHP
php使浏览器直接下载pdf文件的方法
2013/11/15 PHP
简单分析ucenter 会员同步登录通信原理
2014/08/25 PHP
DEDE实现转跳属性文档在模板上调用出转跳地址
2016/11/04 PHP
PHP实现给定一列字符,生成指定长度的所有可能组合示例
2019/06/22 PHP
收藏一些不常用,但是有用的代码
2007/03/12 Javascript
js类中的公有变量和私有变量
2008/07/24 Javascript
尝试在让script的type属性等于text/html
2013/01/15 Javascript
JavaScript中判断变量是数组、函数或是对象类型的方法
2015/02/25 Javascript
简介JavaScript中的setHours()方法的使用
2015/06/11 Javascript
让你一句话理解闭包(简单易懂)
2016/06/03 Javascript
checkbox批量选中,获取选中项的值的简单实例
2016/06/28 Javascript
js querySelector() 使用方法
2016/12/21 Javascript
jQuery实现弹出窗口弹出div层的实例代码
2017/01/09 Javascript
深入理解javascript中的 “this”
2017/01/17 Javascript
javascript事件的传播基础实例讲解(35)
2017/02/14 Javascript
js实现倒计时关键代码
2017/05/05 Javascript
angular或者js怎么确定选中ul中的哪几个li
2017/08/16 Javascript
原生javascript实现的全屏滚动功能示例
2017/09/19 Javascript
jQuery图片查看插件Magnify开发详解
2017/12/25 jQuery
利用vue.js实现被选中状态的改变方法
2018/02/08 Javascript
vue实现与安卓、IOS交互的方法
2018/11/02 Javascript
react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面
2019/11/12 Javascript
[01:00:30]完美世界DOTA2联赛循环赛 Inki vs Matador BO2第二场 10.31
2020/11/02 DOTA
python如何实现远程控制电脑(结合微信)
2015/12/21 Python
Django框架 Pagination分页实现代码实例
2019/09/04 Python
Python文件操作基础流程解析
2020/03/19 Python
泰国王权免税店官方网站:KingPower
2019/03/11 全球购物
管理站站长岗位职责
2013/11/27 职场文书
追悼会上的答谢词
2014/01/10 职场文书
创业计划书的写作技巧及要点
2014/01/31 职场文书
销售提升方案
2014/06/07 职场文书
医院标语大全
2014/06/23 职场文书
员工年终自我评价
2014/09/14 职场文书
2014年大学教师工作总结
2014/12/02 职场文书
Docker下安装Oracle19c
2022/04/13 Servers