最近由于项目的需要,需要做数据抓取,也就是用的curl相关的函数库,在这之前还真心没有接触过这么高大上的东西,然后从刚开始到今天才研究curl算是第四天了,写这篇博客记录一下这几天的一个过程,在使用curl模拟登陆抓取数据过程中需要注意的一些事项,以及介绍一款支持跨平台(windows、linux、mac)的抓包软件 charles(这个软件是收费的,但是你不花钱也可以使用) ,想要尽快上手,必须要去熟悉两个东西:http协议、curl的相关参数选项的作用
一、介绍curl
这是curl的维基百科地址:https://zh.wikipedia.org/wiki/CURL,有兴趣的朋友可以去看看
curl支持的通讯协定:FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP
curl可以做的事情有很多,向我们经常用到很多的就是模拟登陆,抓取一些数据,上传下载文件啥的,其他的一些高深的估计很少接触到,我最近也就接触了模拟登陆啥的
二、curl的使用
curl的使用很简单,主要分为四部:
1>.curl_init();//初始化 cURL 会话
2>.curl_setopt();//设置 cURL 传输选项(这一步也是最重要的,也是最复杂的它有很多参数,大家可以看一下php官方信息:http://php.net/manual/zh/function.curl-setopt.php)
3>.curl_exec();//执行 cURL 会话
4>.curl_close();//关闭 cURL 会话
要想使用好curl,必须去看curl相关的传输参数(http://php.net/manual/zh/function.curl-setopt.php),不需要记住,只要有个印象就行,把常用的几个记住就行了
三、curl模拟登陆
1.准备工作:既然是模拟登陆,那就要像那么回事,要模拟浏览器发生登陆请求一样,所以我们要模拟登陆某个网站之前,需要对该网站进行抓包,来分析这个网站登陆的时候都传了些什么参数、传的参数是否加密、加密方式是什么、发送请求的heder里边都有些啥、传输的方式是啥、是什么通信协议(http、https)、是否有图片验证码、获取的登陆地址是否有重定向302等等这些东西你都要去观察,把这些东西都搞清楚了,你才能进行模拟登陆(当然了,首先你自己要有这个网站的账户密码,不然你拿什么来使用curl模拟登陆,对不对?)
2.开始阶段:
a.获取cookie,这一步至关重要,你要模拟登陆必须要先获取网站的cookie,之前伪造下 USER-AGENT 就可以抓数据,但是现在却不行了,没有cookie的话就相当于没有身份,你都没有身份,那网站肯定拒绝你的任何操作,简单点说这就是个标志,下面是获取cookie的代码:
# 1.获取cookie $cookie_file = dirname(__FILE__) . '/cookie.txt';//保存cookie的文件 $login_url = "http://xxxxxxxxxxxxxx";//登陆页面网址 $cookie_curl = curl_init(); $timeout = 5; curl_setopt($cookie_curl, CURLOPT_URL, $login_url); curl_setopt($cookie_curl, CURLOPT_RETURNTRANSFER, 1);//将curl_exec()获取的信息以字符串返回,而不是直接输出。 curl_setopt($cookie_curl, CURLOPT_CONNECTTIMEOUT, $timeout);//在尝试连接时等待的秒数。设置为0,则无限等待 curl_setopt($cookie_curl, CURLOPT_COOKIEJAR,$cookie_file); //获取COOKIE并存储,在执行curl_close连接介绍,保存获取的cookie的文件 $contents = curl_exec($cookie_curl); curl_close($cookie_curl);
b.获取图片验证码(针对没有图片验证码的网站可以忽略),这一步也是重要的一环,图片验证码要是获取的不正确,你是没有办法登陆成功的
# 2.获取验证码 $cookie_file = dirname(__FILE__) . '/cookie.txt';//保存cookie的文件 $verify_code_url = "http://xxxxxxxxxxxx";//获取图片验证码url $verify_code_referer = "http://xxxxxxxxxxxx";//登陆页面url $verify_curl = curl_init(); curl_setopt($verify_curl, CURLOPT_URL, $verify_code_url); curl_setopt($verify_curl, CURLOPT_COOKIEFILE, $cookie_file);//第一步获取的cookie文件 curl_setopt($verify_curl, CURLOPT_HEADER, 0);//启用时会将头文件的信息作为数据流输出。 // curl_setopt($verify_curl, CURLOPT_HTTPHEADER, array($login_url_header['2']));//获取验证码需要的header数据 curl_setopt($verify_curl, CURLOPT_REFERER, $verify_code_referer);//在HTTP请求头中"Referer: "的内容,访问来源 curl_setopt($verify_curl, CURLOPT_RETURNTRANSFER, 1);//将curl_exec()获取的信息以字符串返回,而不是直接输出。 $img = curl_exec($verify_curl); curl_close($verify_curl); $fp = fopen("verifyCode.jpg","w");//将获取的验证码写入图片中 fwrite($fp,$img); fclose($fp);
注意:(1).获取图片验证码url后面一般会跟一个参数,那就是时间戳(什么毫秒级别的、中国标准时间),有可能需要函数处理一下这些参数,我遇到的是需要使用 urlencode 来处理参数,参数格式什么不正确是获取不到验证码的;(2).那就是代码中注释的一行,CURLOPT_HTTPHEADER 这个参数的作用是设置请求时的header头数据,有些网站比较严格,就需要,还有像什么 CURLOPT_REFERER、CURLOPT_USERAGENT 这些参数,在你试了上面的方法不行的时候,就试着把这几个参数的值补上试试;(3).这里获取了图片验证码,网上有些人是使用代码,暂停20秒,我们人为的去查看这个图片验证码的值,然后写到一个txt的文件中,然后再用file_get_contents读取出我们填写的验证码;当然你也可以使用其他的办法,怎么方便就怎么来吧(代码:sleep(20);$code = file_get_contents("./code_bj.txt");)。
c.拼接登陆需要发送的数据,以及数据是否加密,使用什么方式加密,这些都需要处理,这里的数据不能是二维数组 ,只能是一维数组(key=>value),或者是"&username=zhangsan&password=123456&code=2z2s",以上两种格式都行,在传输数据时,如果是一维数组格式的,需要使用函数 http_build_query 进行相应的处理,代码如下:
//提交的参数有两种格式 # 1.一维数组(绝对不能是二维数组) $post = array( 'username' => 'zhangsan', 'password' => '123456', 'code' => '2z2s', ); # 1.1一维数组格式在传输时需要使用函数(http_build_query)处理 curl_setopt($curl, CURLOPT_POST, 1);//post方式提交 curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post)); # 2.字符串形式 $post = "&username=zhangsan&password=123456&code=2z2s"; # 2.1一维数组格式在传输时需要使用函数(http_build_query)处理 curl_setopt($curl, CURLOPT_POST, 1);//post方式提交 curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
3.模拟登陆,代码如下:
# 3.模拟登陆 $cookie_file = dirname(__FILE__) . '/cookie.txt';//保存cookie的文件 $submit_url = 'http://xxxxxxxxxxxx';//数据提交的url(form表单提交数据的地址) $submit_referer = "http://xxxxxxxxxxxx";//登陆页面url $submit_curl = curl_init();//初始化curl模块 curl_setopt($submit_curl, CURLOPT_URL, $submit_url);//登录提交的地址 curl_setopt($submit_curl, CURLOPT_HEADER, 0);//是否显示头信息 curl_setopt($submit_curl, CURLOPT_RETURNTRANSFER, 1);//将curl_exec()获取的信息以字符串返回,而不是直接输出。 curl_setopt($submit_curl, CURLOPT_COOKIEFILE, $cookie_file); //设置Cookie信息保存在指定的文件中 curl_setopt($submit_curl, CURLOPT_REFERER, $submit_referer);//来源 curl_setopt($submit_curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36");//来路 curl_setopt($submit_curl, CURLOPT_HTTPHEADER, array('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Upgrade-Insecure-Requests: 1','Content-Type: application/x-www-form-urlencoded','Accept-Encoding: gzip, deflate','Accept-Language: zh-CN,zh;q=0.8','Content-Length:'.strlen($post))); curl_setopt($submit_curl, CURLOPT_POST, 1);//post方式提交(这里我使用的数据格式是字符串拼接格式) curl_setopt($submit_curl, CURLOPT_POSTFIELDS, $post);//要提交的信息 $contents = curl_exec($submit_curl);//执行cURL curl_close($submit_curl);//关闭cURL资源,并且释放系统资源
感兴趣的输出上面的结果集,看看是什么就知道了,到此模拟登陆就成功了,接下来就做你想做的事情,比如登陆成功后你要获取你用户个人中心的账户姓名,头像,手机号等等信息都是可以的
4.总结
1.在使用curl的时候,一定要先去看看curl相关参数,不然会带来很无聊的麻烦(本人就是,把CURLOPT_COOKIEJAR和CURLOPT_COOKIEFILE搞错了,结果找了半天才找到原因)
2.在模拟登陆之前一定要仔细分析网站登陆的过程都发生了些什么,使用抓包工具,抓取数据进行分析,一些网站比较严格的,你必须要加上几个参数:CURLOPT_REFERER(访问来源,从哪个网页过来的)、CURLOPT_USERAGENT(仿造来路咯!模拟是google发的请求或者火狐发的请求)、CURLOPT_HTTPHEADER(这个很关键,就是发送请求的网址的请求头--request header,看看里面都有哪些参数,必要的时候,在模拟发请求的时候把这些header参数全部设置上去,成功几率很大哦!)。
3.一定要有耐心,前期把抓包分析工作做仔细,多看看http协议和curl参数,祝君成功!
暂时就先写这么多,以上内容纯属我自己实践,如有错误欢迎批评指正,谢谢!!!