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 动态多文件上传
Jan 18 PHP
PHP 模拟登陆MSN并获得用户信息
May 16 PHP
DW中链接mysql数据库时,建立字符集中文出现乱码的解决方法
Mar 27 PHP
PHP XML error parsing SOAP payload on line 1
Jun 17 PHP
php empty() 检查一个变量是否为空
Nov 10 PHP
PHP Hash算法:Times33算法代码实例
May 13 PHP
php实现scws中文分词搜索的方法
Dec 25 PHP
php中替换字符串函数strtr()和str_repalce()的用法与区别
Nov 25 PHP
PHP闭包定义与使用简单示例
Apr 13 PHP
PHP排序算法之冒泡排序(Bubble Sort)实现方法详解
Apr 20 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
Jun 13 PHP
php命令行写shell实例详解
Jul 19 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代码包装修正版
2008/03/15 PHP
is_uploaded_file函数引发的不能上传文件问题
2013/10/29 PHP
php使用mb_check_encoding检查字符串在指定的编码里是否有效
2013/11/07 PHP
php遍历数组的4种方法总结
2014/07/05 PHP
PHP中的插件机制原理和实例
2014/07/08 PHP
JavaScript与HTML结合的基本使用方法整理
2015/10/12 PHP
php设计模式之单例模式代码
2016/06/11 PHP
非常强大的 jQuery.AsyncBox 弹出对话框插件
2011/08/29 Javascript
动态获取复选框checkbox选中个数的jquery代码
2013/06/25 Javascript
JS正则表达式获取分组内容的方法详解
2013/11/15 Javascript
JS实现鼠标点击展开或隐藏表格行的方法
2015/03/03 Javascript
bootstrap读书笔记之CSS组件(上)
2016/10/17 Javascript
jQuery使用方法
2017/02/04 Javascript
微信小程序 中wx.chooseAddress(OBJECT)实例详解
2017/03/31 Javascript
Node.js中的cluster模块深入解读
2018/06/11 Javascript
详解关于React-Router4.0跳转不置顶解决方案
2019/05/10 Javascript
Vue 3.0 前瞻Vue Function API新特性体验
2019/08/12 Javascript
Python实现单词翻译功能
2017/06/06 Python
使用matplotlib画散点图的方法
2018/05/25 Python
python字符串常用方法
2018/06/14 Python
使用k8s部署Django项目的方法步骤
2019/01/14 Python
python 实现手机自动拨打电话的方法(通话压力测试)
2019/08/08 Python
python新手学习可变和不可变对象
2020/06/11 Python
Python 保存加载mat格式文件的示例代码
2020/08/04 Python
Python random模块的使用示例
2020/10/10 Python
python logging模块的使用详解
2020/10/23 Python
元旦晚会邀请函
2014/01/27 职场文书
上课玩手机检讨书
2014/02/08 职场文书
法英专业大学生职业生涯规划书范文
2014/09/22 职场文书
森马旗舰店双十一营销方案
2014/09/29 职场文书
酒店仓管员岗位职责
2015/04/01 职场文书
2015年后勤工作总结范文
2015/04/08 职场文书
小学生节水倡议书
2015/04/29 职场文书
少先队大队委竞选口号
2015/12/25 职场文书
2016年青少年禁毒宣传教育活动总结(学校)
2016/04/05 职场文书
HTML+CSS实现导航条下拉菜单的示例代码
2021/08/02 HTML / CSS