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

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

更多相关文章

  1. 这是什么原因啊,没有找出错来啊(数据库用的是mysql)
  2. 将数据从一个流传输到另一个流
  3. 使用ORM在不在数据库中的表上的外键
  4. PHP5中数据库抽象层: PDO
  5. PHP用于解析JSON并添加到数据库mysql
  6. 加入vs多个数据副本:性能
  7. MySQL多个连接到付款数据的日历表
  8. MYSQL 导入53M数据报错
  9. 解决Navicat数据传输问题:The‘InnoDB’feature is disabled; yo

随机推荐

  1. Python能不能方便的画三角形?
  2. win8.1 cygwin - pip正在安装到windows p
  3. 使用Python启动浏览器(Chromium)并更改URL
  4. python 读写文本文件
  5. 用 Python 分析胡歌的《猎场》到底值不值
  6. Python: sorted和sort的区别
  7. Python闭包需要注意的问题
  8. 使用python将图片转换为字符图片
  9. 如何按期执行python脚本?
  10. python 3.3 爬虫之爬取图片