用curl模拟登陆获取页面信息以及相关知识点
今天使用curl做了模拟登陆,之前没有接触过curl,也并不知道有这个东西,下面简要谈谈我在做这个模拟登陆过程中get 到的技能以及了解到的知识:
1、CURL:curl是利用URL语法开发的开源传输工具,相当于一个模拟浏览器,可以通过post/get获取到想要的页面信息、实现文件的上传下载、操作cookies文件、通过代理服务器(代理服务器是浏览器和web服务器的一个中转站,相当于缓冲池)向服务器发送请求等,支持如FTP,FTPS,TELNET等多种文件传输协议。起初只能在命令行中使用,现在也支持PHP,并且有一个强大的函数库,里面有很多函数可以支持不同的功能。之前采集页面信息的时候用的是file_get_contents,采集完整个页面,然后再用正则匹配获取到想要的内容,对于某些登陆或者验证后才能得到的信息是获取不到的。
curl发送url请求的步骤为:curl初始化---》 设置具体的参数信息---》执行curl,并取得返回的结果---》关闭curl会话
下面就是使用curl模拟登陆获取用户信息的过程:
<span style="font-size:14px;">function login_post($url, $cookie, $post){ $curl = curl_init($url);//初始化 curl_setopt($curl, CURLOPT_URL, $url);//登录提交的地址 curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie); //设置Cookie信息保存在指定的文件中 curl_setopt($curl, CURLOPT_POST, 1);//post方式提交 curl_setopt($curl, CURLOPT_POSTFIELDS, $post);//要提交的信息 //var_dump(http_build_query($post));exit;//打印要post的信息 $data = curl_exec($curl);//执行命令 curl_close($curl);//关闭URL请求 } function get_content($url, $cookie) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_URL, $url);//需要获取信息的页面 //curl_setopt($ch, CURLOPT_HEADER, 1);//不输出头部 curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);//设置将获取到的信息输出在浏览器上 curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); //读取cookie $rs = curl_exec($ch); //执行cURL抓取页面内容 curl_close($ch); return $rs; } //设置post数据 $post = array( "uname" => "xxxxxxxx", "passwd" => "xxxxxx", …… );//这里要传输的数据很重要,决定了能否成功登陆页面,生成cookie文件 //其实只要post的数据正确,一般都能生成cookie文件,之后就很简单了。 </span> //登录地址 $url = "URL"; $cookie = dirname(__FILE__) . "/cookie.txt";</span><span style="font-size:14px;"> // 设置cookie保存路径</span><span style="font-size:14px;"> $url2 = "URL";</span><span style="font-size:14px;"> //登录后要获取信息的页面</span><span style="font-size:14px;"> login_post($url, $cookie, $post);</span><span style="font-size:14px;">// 模拟登录</span><span style="font-size:14px;"> $content = get_content($url2, $cookie);</span><span style="font-size:14px;">//获取登录页的信息</span><span style="font-size:14px;"> echo $content."<hr/>";//匹配页面信息 $preg = "/d{4}-d{2}-d{2} d{2}:d{2}:d{2}/i"; $bool = preg_match($preg,$content,$time); echo "注册时间:".$time[0]</span>;
2、php抓取页面信息的方式还有以下几种
(1)file_get_contents($url) 会抓取整个页面,打印返回的结果是整个页面
(2)file($url) 会抓取整个页面,打印返回的结果是数组(将页面拆分后的结果),implode之后再打印就是整个页面
(3)fopen() 要配合fread()和fclose()一起使用,抓取整个页面,处理过后也可以打印整个页面
3、cookie的原理
cookie就是服务器在响应客户端请求的时候通过在http响应头上加一段特殊指示(创建一个cookie对象)从而使浏览器自动生成的一个保存用户信息和状态的小文件。cookie只在客户端发送请求或者浏览器自己具有创建cookie功能的时候会创建。cookie有会话cookie(保存在内存中,一旦浏览器关闭则自动销毁,多窗口不能共享)和持久cookie(保存在硬盘中,到了过期时间才会销毁,同一个浏览器的多个窗口可以共享)。浏览器在发送请求的时候会在客户端寻找是否有相应作用范围的cookie文件,如果有就会将cookie放在http的请求头中一起发送给服务器,服务器再响应相应的内容。cookie内容主要包括:名字、值、过期时间、路径和域(这两者即构成cookie的作用范围)
4、session的原理
session是保存在服务器端的信息,散列表的结构。当浏览器向服务器端发送请求的时候,如果请求头中有sessionid(一般会存在于cookie中,和cookie一起通过请求头发送),那么服务器会根据这个sessionid找到服务器上这个id对应的内容,根据请求信息决定是否把相关信息返回给客户端,如果没有,则会为这个用户创建一个session(在服务器端调用HttpServletRequest.getSession(true)这种语句的时候才会创建,并且可以由用户决定是创建文件还是数据表等的形式),并将sessionid返回给浏览器并保存。浏览器端传递sessionid的方法可以有多种:
(1)在cookie中保存sessionid,发送请求的时候直接附加在请求头中
(2)通过URL重写来发送sessionid,即把sessionid加在url的后面
步骤:
1)在服务器端php.ini配置文件中设置:session.use_cookies = 0 && session.use_only_cookie = 0 session.use_trans_sid = 1
2)如果你使用的是nginx,那么在nginx的文件根目录下创建一个index.php,内容如下:
<?php session_start(); echo session_id(); echo "<a href="">aa</a>"; ?>然后
I. 使用php命令直接在dos下解析php文件(如:php index.php),这个时候就会有问题出现:
如果你的lnmp服务器中php的版本是5.7以上的版本,那么在执行上述php index.php的时候是会报错的,我这里是报 core dumped;
II. 在浏览器通过ip访问这个文件的时候也会报错
如果你在浏览器设置中禁用了cookie,那么你每刷新一次页面,浏览器就会向服务器发送一次请求,但是因为php.ini中我们设置了sessionid不通过cookie传递,那么在这次请求的头中就没有sessionid的信息传递给服务器,服务器接收了请求之后,没有发现sessionid,那么它会自动生成一个session文件,然后将sessionid响应给客户端,那么这个时候客户端禁用了cookie之后,就不能用cookie来保存这一个sessionid,所以当你再次刷新页面的时候,sessionid就不能传递给服务器端进行比对,服务器端就又会生成一个新的session文件,每刷新一次生成一个。
所以,客户端不能够设置禁用cookie,只需要设置php.ini就可以 了,并且php版本最好是5.6及以下,那么就能顺利在url中看到sessionid
那么做到这一步了之后,继续深究又会发现问题,比如:
session_url.php:
<span style="font-size:14px;"><?php session_start(); $_SESSION["vars"] = "HELLO WORLD"; //echo "<a href="">aa</a>";//点击aa可以看到sessionid加到了url中 //echo "<a href="http://172.16.233.128/a.php">aa</a>";//sessionid没有加到url中,并且没有打印出a.php中的结果 echo "<a href="a.php">aa</a>";//点击aa可以看到sessionid加到了url中,并且可以打印出a.php中的session中的值,同时你查看 //页面源代码的时候发现a标签中的href也已经加上了sessionid ?></span>a:php:
<span style="font-size:14px;"><?php echo $_SESSION["vars"]; ?></span>上面的结果差异性问题可能是跟nginx的行为有关系,具体没有做更深入的探究,但是在没有加ip地址的时候,如果是同一个域内的文件,一般来说都是可以在url上自动加上sessionid
(3)通过隐藏表单的形式来传递sessionid,服务器会自动修改表单
可以在form表单中设置一个隐藏input将session_id()传递给后端,也可以在后端直接获取到session_id(),可以直接使用,也可以保存到文件中,这样在访问同一台服务器上的不同域的时候可以使用同一个sessionid;将session信息保存到数据库中,然后另外一台服务器也可以拿着文件中的sessionid来访问这台服务器中的session信息,实现session共享
5、session和cookie的区别
session保存在服务器端,默认通过cookie的方式保存sessionid,所以如果客户端禁用了cookie,在服务器端又没有设置trans-sid选项的话,那么sessionid是没有地方保存的,那么session也就用不了;sessionid一般保存在会话cookie中,所以一般关闭浏览器就找不到这个sessionid了;安全性较高,可以存储用户名密码之类的重要信息。
cookie保存在浏览器端,安全性没有session那么高,可以存储一些不太重要的信息。
6、服务器比对验证码的机制
服务器端在客户端请求的时候,首先随机生成一串字符串保存在session中,然后将字符串写入图片,发送给浏览器显示,客户输入看到的字符串,返回给服务器端,与session中保存的字符串进行比对。
7、hosts文件和dns域名解析系统
hosts文件中存储的是ip和域名的一个对应关系。用户在访问一个域名的时候,需要找到该域名对应的ip,那么首先,客户端会先给本地域名服务器发送请求,本地域名服务器会在自己的映射表中查找是否有这个域名对应的ip,如果有,则向客户端返回这个ip,如果没有,那么就会继续发送请求给根域名服务器,根域名服务器在自己的映射表中查找所请求的那个域的主域名服务器的ip,然后返回给本地dns,本地dns再向主域名服务器发送请求,主域名服务器要是没有找到映射关系的话,就会返回下一级的域名服务器ip,直到找到正确的ip,然后返回给本地dns,然后本地dns会将此映射关系写入缓存,同时返回给客户端。
8、http和https
用户在使用浏览器发送请求的时候使用的是http和https协议,这两种都是超文本传输协议,区别是,https是加密传输协议,使用了ssl套接字层,对数据进行加密了之后再传输,且需要申请数字证书,由服务器端将证书发送给客户端,客户端先验证这个证书是否可信任,如果可信任,那么就会生成一个随机值,然后用这个证书给随机值加密,然后将加密后的随机值发送给服务器端,服务器端用证书进行解密,之后服务器端和客户端的通信就靠这个随机值对数据进行加解密传输。http和https都是建立在TCP/IP协议的基础之上,是可靠的连接。
9、http请求返回的状态码
1xx : 提示信息
2xx :成功
3xx :重定向
4xx :客户端错误
5xx :服务器端错误
比较常见的是302(请求网页临时移动到新位置)、403(服务器拒绝请求)、404(找不到文件)、500(服务器遇到错误)等
状态码详解:http://tool.oschina.net/commons?type=5
- 上一篇: JS 删除字符串最后一个字符的几种方法
- 下一篇: php解决session跨域,验证码无效问题。