代码改变世界

php curl模拟登陆抓取数据

2017-05-05 18:33  ZengGW  阅读(3207)  评论(0编辑  收藏  举报

  最近由于项目的需要,需要做数据抓取,也就是用的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_REFERERCURLOPT_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参数,祝君成功!

 

  暂时就先写这么多,以上内容纯属我自己实践,如有错误欢迎批评指正,谢谢!!!