php通过cURL爬取数据(1):ajax接口、cookie伪造爬取、文件头信息

192 篇文章 3 订阅

  • cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP、FTP、TELNET等。当然,PHP也支持 cURL 库,用来模拟浏览器访问网页、上传文件、下载文件等操作。
  • cURL 通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。cURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。

一、请求流程

使用CURL的PHP扩展完成一个HTTP请求的发送一般有四个步骤:

1.CURL请求步骤

  1. 初始化连接句柄;
  2. 设置CURL选项;
  3. 执行并获取结果;
  4. 释放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的方式:curl_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等工具进行爬取操作;

@漏刻有时

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
如果你想要使用 PHP 接收通过 AJAX 发送的文件,并通过 cURL 转发文件内容,可以按照以下步骤进行操作: 1. 前端 AJAX 请求: ```javascript var fileInput = document.getElementById('fileInput'); var file = fileInput.files[0]; var formData = new FormData(); formData.append('file', file); var xhr = new XMLHttpRequest(); xhr.open('POST', 'upload.php', true); xhr.onload = function() { if (xhr.status === 200) { console.log('文件上传成功'); } else { console.log('文件上传失败'); } }; xhr.send(formData); ``` 在上面的示例中,我们使用 `FormData` 对象来创建一个表单数据,并将文件添加到表单中。然后,我们使用 `XMLHttpRequest` 对象发送 POST 请求到 `upload.php` 文件,将表单数据作为请求体发送。 2. 后端 PHP 文件(upload.php): ```php <?php // 获上传的文件 $file = $_FILES['file']; // 构建 cURL 请求 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://目标地址'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, [ 'file' => new CURLFile($file['tmp_name'], $file['type'], $file['name']) ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 发送 cURL 请求 $response = curl_exec($ch); curl_close($ch); // 输出 cURL 响应 echo $response; ?> ``` 在上面的 PHP 文件中,我们首先通过 `$_FILES['file']` 获上传的文件信息。然后,我们使用 cURL 构建一个 POST 请求,设置目标地址、请求体(包含上传的文件),以及其他必要的选项。最后,我们使用 `curl_exec()` 发送 cURL 请求,并使用 `echo` 输出 cURL 的响应。 确保将目标地址替换为你实际的目标地址。 这样,当前端通过 AJAX 发送文件时,PHP 将接收文件并使用 cURL文件内容转发到目标地址。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漏刻有时

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值