php通过curl爬取数据
- 一、请求流程
- 1.CURL请求步骤
- 2.使用CURL发送GET请求
- 3.使用CURL发送POST请求
- 二、实战:curl通过ajax接口API爬取数据
- 1.接口分析
- 2.抓取分析
- 3.构建curl
- 4.结果呈现
- 三、实战:curl添加cookie伪造登陆爬取数据
- 1.注册用户,并记录信息;
- 2.构建curl
- 3.阻止cURL爬取
- cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP、FTP、TELNET等。当然,PHP也支持 cURL 库,用来模拟浏览器访问网页、上传文件、下载文件等操作。
- cURL 通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。cURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。
一、请求流程
使用CURL的PHP扩展完成一个HTTP请求的发送一般有四个步骤:
1.CURL请求步骤
- 初始化连接句柄;
- 设置CURL选项;
- 执行并获取结果;
- 释放VURL连接句柄
2.使用CURL发送GET请求
使用CURL来发送GET请求,发送GET请求的关键是拼装格式正确的URL。请求地址和GET数据由一个“?”分割,然后GET变量的名称和值用“=”分隔,各个GET名称和值由“&”连接。PHP为我们提供了一个函数专门用来拼装GET请求和数据部分——http_build_query,该函数接受一个关联数组,返回由该关联数据描述的GET请求字符串。
function get_Data($url, $data)
{
$url = $url . '?' . http_bulid_query($data);
//初始化
$curl = curl_init();
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, $url);
//设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 0);
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//执行命令
$result = curl_exec($curl);
//关闭URL请求
curl_close($curl);
//显示获得的数据
return $result;
}
3.使用CURL发送POST请求
使用CURL提供的选项CURLOPT_POSTFIELDS,设置该选项为POST字符串数据就可以把请求放在正文中。
/*
* $url,获取地址;
* $data,传输参数,array();
* */
function post_Data($url, $post_data)
{
//异常控制;
if ($url == '' || $post_data == '') {
return "传递参数错误,无法获取数据.";
}
//初始化
$curl = curl_init();
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, $url);
//设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 0);
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//设置post方式提交
curl_setopt($curl, CURLOPT_POST, 1);
//设置post数据
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
//执行命令
$result = curl_exec($curl);
//关闭URL请求
curl_close($curl);
//显示获得的数据
return $result;
}
- 当
curl_setopt($curl, CURLOPT_HEADER, 1);
时,输出的内容带文件头信息。如果仅获取json格式,可以设置为curl_setopt($curl, CURLOPT_HEADER, 0);
HTTP/1.1 100 Continue HTTP/1.1 200 OK Content-Type: text/html;charset=utf-8 Server: Microsoft-IIS/8.5 X-Powered-By: PHP/5.4.45 Set-Cookie: ZDEDebuggerPresent=php,phtml,php3; path=/ Date: Thu, 27 Apr 2023 04:21:44 GMT Content-Length: 2722 {"res":[{"id":"1","code":"shinan","name":"\u60a6\u9014","longitude":"108.721996","latitude":"34.090917","resourceAmount":"0","url":"#"},
- 文件流输出:
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。
**但具体文件流输出和直接输出的区别在哪里?**暂时没有找到具体的资料。直接输出,是不能数据结构化的,这个是目前发现的唯一区别。
二、实战:curl通过ajax接口API爬取数据
1.接口分析
分析某文件ajax接口,通过post获取后端数据
2.抓取分析
- 获取方法: type: “post”,
- 获取地址:url: ‘php/index.php’,
- 传输参数:data: {“caozuo”:“gethouse”,“search_name”:search_name},
3.构建curl
/*
* $url,获取地址;
* $data,传输参数,array();
* */
function postContent($url, $data)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
//执行操作
$url = "http://test.com/php/index.php";
$data = array('caozuo' => 'getarea', 'search_name' => '');
4.结果呈现
三、实战:curl添加cookie伪造登陆爬取数据
1.注册用户,并记录信息;
2.构建curl
function get_cookies_content($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
$header = array();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_COOKIE, 'db_user_name=楚云飞;PHPSESSID=343qv378qug069rv7uu1hk5mj6;admin_id=1;admin_roles=0;admin_menu=1;');
$content = curl_exec($ch);
echo $content;
echo "<pre>错误信息:";
print_r(curl_error($ch));
echo "</pre>";
echo "<pre>内容:";
print_r(curl_getinfo($ch));
echo "</pre>";
echo "<pre>标题头:";
print_r($header);
var_dump(curl_version());
}
- 传递cookies的方式:c
url_setopt($ch, CURLOPT_COOKIE, 'db_user_name=楚云飞;PHPSESSID=343qv378qug069rv7uu1hk5mj6;admin_id=1;admin_roles=0;admin_menu=1;');
- cookies的写法:
db_user_name=楚云飞;PHPSESSID=343qv378qug069rv7uu1hk5mj6;admin_id=1;admin_roles=0;admin_menu=1;
将使用到的cookies值通过=
赋值,;
进行分割传递即可。
3.阻止cURL爬取
在实战中发现,如果要想阻止爬取,增加判断盐值是SESSION即可:$row['user_salt'] !== session_id()
//判断session_id是否一致,强制退出;
global $db;
dbc();
$user_id = AuthCode($_COOKIE['db_user_id'], 'DECODE', '', '');
$row = $db->fetch('user', 'user_salt', array('user_id' => trim(addslashes($user_id))), ' user_id DESC');
if ($row['user_salt'] !== session_id()) {
redirect('?m=Login&a=loginDeal&act=LoginOut');
}
$user_id = AuthCode($_COOKIE['db_user_id'], 'DECODE', '', '');
对cookies中的明文$user_id加密处理,防止越权使用或通过漏洞进行渗透;- 设置登录权限,判断当前登录用户是否和浏览器使用一致,防止通过curl等工具进行爬取操作;
@漏刻有时