php使用guzzlehttp/guzzle进行数据采集

  • 一、需求目的
    • 1、采集某个平台网站的数据
    • 2、将采集回来的数据与本身平台系统的现有数据汇总
  • 二、实现步骤
    • 1、分析平台网站
    • 2、确定方案
    • 3、封装功能类
    • 4、使用功能类进行后续处理
  • 三、具体实现
    • 开启数据抓取脚本
    • 开启数据同步脚本
    • 界面展示

一、需求目的

1、采集某个平台网站的数据

2、将采集回来的数据与本身平台系统的现有数据汇总

二、实现步骤

1、分析平台网站

  • 分析登录校验方式

    • session 或 token
  • 分析界面数据渲染方式
    • 异步数据渲染 或 直接页面和数据一起渲染

2、确定方案

  • 分析后,发现网站的登录比较简单,直接账号密码登录即可,并且登录校验是通过cookie进行校验的
  • 分析后,发现界面数据的渲染方式是异步数据渲染,代表有接口可以返回数据,直接对接口进行请求即可

3、封装功能类

确认完方案后,为了后续使用方便,特意封装一个功能类,其他地方使用的时候就比较简单
一、设置基础信息
- 设置对应平台域名
- 设置对应的账号密码
- 设置cookie序列化后保存的路径
二、功能方法
- 获取句柄方法(带cookie)
- 认证授权方法
- 带cookie的请求方法
- 简单的http方法
- 外部API返回处理方法
- 某个数据列表页面的获取等

4、使用功能类进行后续处理

三、具体实现

开启数据抓取脚本
使用功能类获取某个数据列表接口,得
```json
{'count'=>10000,'data_list'=>[{...}]
}
```
获取这批数据在数据库的流水号,并分开保存在数据库表 log 中(为了后续有个计算抓取进度,我把这个数据保存放在了功能类中,每获取完一次接口,都先保存到数据库,同时还保存了要抓取的总数量)
开启数据同步脚本

读取数据库 log 表,按id升序取n条记录
循环记录列表
设置记录状态修改为处理中
具体同步的逻辑(每个人不一样,这里就不展开了)
将记录状态修改为已完成(或者处理失败等)

界面展示

其他数据展示就不说了,这里写一下进度条的展示

找个进度条的代码样式(网上应该很多,我这里用的是后台管理模版自带的)

获取进度数据

  • 数据抓取进度

    • 获取log表最后一条数据的流水号,并得到该流水号要获取的总数量
    • (总数量/每次获取的数量)+1 ,得到该流水号共有多少条记录
    • 总记录数量/当前流水号的记录数量,得数据抓取进度
  • 数据同步进度
    • 获取同批流水号记录,通过状态 未处理 等状态判断未处理和已处理的数量
    • 已处理 / 总数量,得数据同步进度
  • 将进度和当前属于哪种进度的相关信息返回(界面简单通过定时器和ajax,所以可以看到进度条和文字在变化)

功能类代码

<?phpnamespace App\Common\Features;use App\Common\Models\SyncLog;
use App\Common\Repositories\LogRepositorie;
use App\Exceptions\ErrorCode;
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Cookie\SetCookie;
use Illuminate\Support\Facades\Redis;class Feature
{//地址private $apiHost;//账号private $username;//密码private $password;//cookie保存路径private $cookieJar;private $cookie;private $client;private $LogRepo;public function __construct(){$this->apiHost = '';$this->username = '';$this->password = '';$this->cookieJar = 'cookie/login.cookie';$this->LogRepo = new LogRepositorie();}/*** 获取句柄* @return Client*/public function getClient(){if (empty($client)) {$this->cookie = new CookieJar;$this->client = new Client(array('cookies' => $this->cookie));}return $this->client;}/*** 认证授权* @throws \GuzzleHttp\Exception\GuzzleException*/public function auth(){$retryCount = 3;//认证问题不通过3次重试$response = null;while ($retryCount > 0) {$retryCount--;try {$isAuth = false;try {//获取cookie和句柄$cookieContent = file_get_contents($this->cookieJar);$cookieObject = unserialize($cookieContent);//$client = new Client(array('cookies' => $cookieObject));$response = $client->request('GET', $this->apiHost . '/xxx');//先尝试请求某个要登录的接口$result = $this->loadResult($response);$this->client = $client;//如果成功则句柄和cookie有效$this->cookie = $cookieObject;return;} catch (\Exception $e) {$isAuth = true;}//判断是否需要登录if ($isAuth) {//使用登录接口$this->getClient();$result = $this->client->request('POST', $this->apiHost . '/login', ['timeout' => 30,'form_params' => ['username' => $this->username,'password' => $this->password,]]);//登录成功保存cookie$cookie = $this->cookie;$cookieContent = serialize($cookie);file_put_contents($this->cookieJar, $cookieContent);}$retryCount = 0;return;} catch (\Exception $e) {}}//抛异常}public function dataSearch(){$uri = '/xxx';//获取记录批次流水$serial_number = $this->LogRepo->getSerialNumber(['uri' => $uri]);//循环获取数据$flag = true;$pageSize = 500;$page = 1;$totalItems = 0;$orderArrayList = [];while ($flag) {$request = ['pageSize' => $pageSize,'page' => $page,];$request_type = 'post';$result = $this->request($uri, $request_type, $request, $serial_number);if (!empty($result['list'])) {$orderArrayList[] = $result['list'];} else {$totalItems = $result['totalItems'];$flag = false;}echo '共 ' . (ceil(($result['totalItems'] / $pageSize)) + 1) . " 页,第 " . $page . ' 页结束,' . date('Y-m-d H:i:s') . "\n";sleep(5);$page++;}$response = ['count' => count($orderArrayList),'data_list' => $orderArrayList,];return $response;}/*** 带cookie的请求方法* @param $uri* @param string $method* @param array $queryData* @param string $serial_number* @param string $resultType* @return false|mixed|string* @throws \GuzzleHttp\Exception\GuzzleException*/public function request($uri, $method = 'get', $queryData = [], $serial_number, $resultType = 'array'){//这里新增记录,为了后续的进度统计$syncLog = $this->LogRepo->addSyncLog(['uri' => $uri,'serial_number' => $serial_number,'request_type' => $method,'request' => $queryData,]);$syncLogId = $syncLog['id'];$this->auth();$result = $this->http($uri, $method, $queryData, [], $resultType);//更新同步记录的结果$this->LogRepo->updateSyncLog(['id' => $syncLogId], ['response' => $result,'status' => SyncLog::STATUS_WAIT_SYNC,'grab_time' => time(),]);return $result;}/*** 简单的http方法* @param $uri* @param string $method* @param array $queryData* @param array $headerData* @param string $resultType* @return false|mixed|string* @throws \GuzzleHttp\Exception\GuzzleException*/public function http($uri, $method = 'get', $queryData = [], $headerData = [], $resultType = 'array'){$url = $this->apiHost . $uri;$headers = ['Content-Type' => 'application/x-www-form-urlencoded'//'Content-Type' => 'application/json;charset=UTF-8'];if (is_array($headerData)) {$headers = array_merge($headers, $headerData);}$params = [];if (!empty($queryData) && is_array($queryData)) {if ($method == 'get') {$params['query'] = $queryData;} else {if ($headers['Content-Type'] == 'application/x-www-form-urlencoded') {$params['form_params'] = $queryData;} else {$params['json'] = $queryData;}}}if (!empty($headers) && is_array($headers)) {$params['headers'] = $headers;}$response = $this->client->request($method, $url, $params);$result = $this->loadResult($response);if (strtolower($resultType) == 'array') {return $result;} else if (strtolower($resultType) == 'json') {return json_encode($result, true);}}/*** 外部API返回处理* @param $response* @return mixed*/protected function loadResult($response){$response_code = $response->getStatusCode();$result = $response->getBody()->getContents();$result = json_decode($result, true);if (!isset($result['success']) || $result['success'] != true) {}return $result['data'];}
}

php使用guzzlehttp/guzzle进行数据采集相关推荐

  1. [VN2020 公开赛]TimeTravel(guzzlehttp/guzzle使用以及HTTPOXY漏洞)

    文章目录 0X01 Guzzle简介 0X01 Guzzle实验 [GET请求] [POST请求] [设置代理IP] 0x03 TimeTravel题目复现 0X01 Guzzle简介 Guzzle是 ...

  2. laravel 安装guzzlehttp/guzzle

    composer require guzzlehttp/guzzle Guzzle是一个PHP HTTP客户端,可以轻松发送HTTP请求,并且可以轻松集成Web服务. 用于构建查询字符串,POST请求 ...

  3. [guzzlehttp/guzzle]使用起来更优雅的HTTP客户端

    在处理业务时,我们总是会发起一个http请求,比如请求远程接口,或者下载一个文件.很显然,在PHP中需要使用CURL,但是curl写起来实在是太不舒服了,又难写,也不易阅读.实际上PHP有很多扩展可以 ...

  4. PHP实战:guzzlehttp/guzzle下载网络文件到本地

    环境 $ php -v PHP 7.1.23 依赖 composer require "guzzlehttp/guzzle=6.5" composer require " ...

  5. guzzlehttp/guzzle 包设置超时

    laravel 框架 guzzlehttp/guzzle包设置超时 摘要:GuzzleHttp\Client 在readme.txt文件没有详细说明它的配置参数,需要配置http请求超时的进. 直接上 ...

  6. php中 可替代curl,laravel-PHP-为什么使用Guzzle代替cURL?

    为什么要使用Guzzle? 首先,Guzzle是HTTP请求的抽象层,尽管默认情况下它使用cURL,但是您可以使用所需的任何其他HTTP客户端: Guzzle是否需要cURL? 不行.Guzzle可以 ...

  7. PHP guzzle异步请求数据,怎么在PHP中使用Guzzle执行POST和GET请求

    怎么在PHP中使用Guzzle执行POST和GET请求 发布时间:2021-02-17 08:01:14 来源:亿速云 阅读:67 作者:Leah 怎么在PHP中使用Guzzle执行POST和GET请 ...

  8. Laravel 中使用Goutte + GuzzleHttp 组件设置 headers无效的原因探究以及解决方案

    我的个人博客:逐步前行STEP 使用Goutte + GuzzleHttp 爬取网页时,如下代码中的请求头设置无效: $jar = CookieJar::fromArray(["HMACCO ...

  9. 关于guzzleHttp的基础操作

    Guzzle是一个PHP的HTTP客户端,用来轻而易举地发送请求,并集成到我们的WEB服务上.Guzzle有许多特点,这里引用官网上的介绍 接口简单:构建查询语句.POST请求.分流上传下载大文件.使 ...

最新文章

  1. Selenium指定浏览器路径
  2. Android应用内展示word、excel、pdf、ppt等文件
  3. js文件引用方式及其同步执行与异步执行
  4. linux里的挂载错误无法开机怎么办,Linux基础知识 - 开机挂载错误
  5. LiveVideoStack线上交流分享 (十七) —— AV1编码器优化与实用落地演进之路
  6. Ubuntu18.04之man中文版
  7. 程序员算法之找出链表的第K个结点
  8. vivo的Android升级包,【原厂固件】vivo y66ia系统升级rom刷机包_卡刷包_PD1621B_A_1.9.6...
  9. 基于java的奖学金评定管理系统_基于java的奖学金评定系统
  10. 《商业俏佳人》游戏体验文档
  11. 阿里巴巴国际站Dropshipping模式探索
  12. 数据库中查询经纬度距离远近
  13. DTI预处理及概率性纤维束追踪
  14. 2023年房地产地段研究报告
  15. Java 8 list 对象字段升序降序
  16. NXP-MPC5748G车载MCU使用(食用)方法(踩坑)实用指南(骗人教程)(二):使用FREERTOS点亮LED
  17. 个人项目——基于STM32的智能物联网寝室
  18. 计算机自带的配置检测,Windows10系统自带电脑硬件设备检测工具的使用步骤
  19. 索引,主键,唯一索引,联合索引的区别
  20. EXTJS 6 - 日期控件 Date picker 只选年月

热门文章

  1. Excel的公式和函数
  2. c语言中一些常用的逻辑运算,C语言中的位运算和逻辑运算
  3. (记) Deployment设置环境变量不生效
  4. 001-编辑器工作区 srt字幕文件
  5. 两美媚张家界凤凰自助游
  6. 数据备份与恢复以及触发器介绍
  7. Effective C++ 日积月累
  8. 确定kafka对应的zookeeper版本
  9. 2021年电工(初级)考试报名及电工(初级)考试资料
  10. Github每日精选(第23期):macOS下的开源清理工具lemon-cleaner