使用guzzlehttp异步多进程实现爬虫业务

news/2024/12/13 14:29:23
Python和PHP核心技术共享平台
Python和PHP核心技术共享平台

背景

小哥近来在通过动态代理池爬取一些公司需要的大文件pdf规格书的处理。遇到的难点,如何保证服务器CPU、连接数等正常情况下,多进程、异步快速处理这些业务并且保证准确。下面小哥就给看官唠嗑一下,我使用guzzlehttps如何处理的这一业务需求的。

guzzlehttp

梳理逻辑

  • 多进程处理

    保证并发处理,提高处理效率

  • 异步处理

    有些数据可能响应很快,有些很慢,不能因为一个进程阻塞其它业务正常执行影响爬取效率。

详细代码

 /*** 使用guzzleHttp多进程异步远程下载文件* @param array $urlMap 多个远程爬取链接* @param string $localPath 本地保存路径*/public function downloadByGuzzlePoolAsync(array $urlMap,$localPath)
{//代理$proxy = 'http://http-dynamic-S04.xzzdaili.com:10030';$proxyUser = '1169461750313049664';$proxyPassword = 'lG9sMtTp';$proxyAuth = base64_encode($proxyUser . ":" . $proxyPassword);
​$header = ['User-Agent'    => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36','Referer'       => 'https://exmaple.com','Proxy-Authorization'  => "Basic " . $proxyAuth,'Content-Type'  => 'application/pdf','content-encoding' => 'gzip, deflate, br, zstd','Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',];
​$client = new Client();
​$requests = function ($urlMap) use ($client,$localPath,$proxy,$header) {foreach ($urlMap as $url){yield $client->getAsync($url,['headers'   => $header,'proxy'     => $proxy,'verify' => false,'stream' => true,'sink' => $localPath])->then(function($resp) {echo "远程规格书获取成功,resp=" . jsonD($resp->getBody()) . PHP_EOL;},function($reason){echo '远程规格书获取失败 :'.$reason. PHP_EOL;});}};
​$pool = new \GuzzleHttp\Pool($client, $requests($urlMap), ['concurrency' => 5,//进程数'options' => ['timeout' => 10, // 设置超时s],'fulfilled' => function (Response $response, $index) use($localPath){//TODO 处理接口成功结果逻辑
​// 创建请求$zacStream = fopen($localPath, 'wb');//流速写入文件:while (!$response->getBody()->eof()) {fwrite($zacStream, $response->getBody()->read(1024 * 1024)); // 读取1MB的数据}fclose($zacStream);echo 'GuzzleHttp进程池响应成功,index=' . $index . ' response=' . $response->getReasonPhrase() . PHP_EOL;
​},'rejected' => function (RequestException $reason, $index) {//TODO 处理接口失败结果逻辑
​echo 'index=' . $index . ' ,error=' .$reason->getMessage() . PHP_EOL;},]);
​$promise = $pool->promise();
​// 捕获请求异常$promise->then(function () {echo "所有请求都已成功完成" .PHP_EOL;},function (RequestException $e) {echo "发生了异常: " . $e->getMessage() . PHP_EOL;});
​// 等待所有请求完成$promise->wait();
​
//        // 访问每个请求的响应
//        foreach ($pool->getRequests() as $request) {
//            echo $request->getUri() . "\n";
//        }
​}
}

以上是小哥本人文章的全部内容,希望总结会帮助到各位看官。最后,小哥温馨提示:每天阅读3分钟,天天学习一点点,天天进步一点点。


https://dhexx.cn/news/show-5466360.html

相关文章

《JavaEat:探索 Java 在美食世界的奇妙之旅》

在当今数字化的时代,编程语言的应用领域不断拓展,而 Java 作为一种广泛使用且功能强大的编程语言,其影响力早已超越了传统的软件开发范畴。当我们将目光聚焦在美食领域时,会惊喜地发现 Java 也能在其中发挥独特而重要的作用。本文…

Web 表单开发全解析:从基础到高级掌握 HTML 表单设计

文章目录 前言一、什么是 Web 表单?二、表单元素详解总结前言 在现代 Web 开发中,表单 是用户与后端服务交互的重要桥梁。无论是用户登录、注册、搜索,还是提交反馈,表单都无处不在。在本文中,我们将从基础入手,全面解析表单的核心知识点,并通过示例带你轻松掌握表单开…

HarmonyOS Next 模拟器安装与探索

HarmonyOS 5 也发布了有一段时间了,不知道大家实际使用的时候有没有发现一些惊喜。当然随着HarmonyOS 5的更新也带来了很多新特性,尤其是 HarmonyOS Next 模拟器。今天,我们就来探索一下这个模拟器,看看它能给我们的开发过程带来什…

【时间之外】IT人求职和创业应知【48】-通信技术

目录 新闻一:腾讯科技取得数据显示相关专利 新闻二:中国5G网络规模全球最大,6G技术取得突破 新闻三:亚马逊启动“登月”计划,部署10万颗二代自研芯片 连亚马逊这样的大厂也搞登月计划,可见现在的业界竞争…

SickOs: 1.1靶场学习小记

学习环境 kali攻击机:Get Kali | Kali Linux vulnhub靶场:https://download.vulnhub.com/sickos/sick0s1.1.7z 靶场描述: 这次夺旗赛清晰地模拟了在安全环境下如何对网络实施黑客策略从而入侵网络的过程。这个虚拟机与我在进攻性安全认证专…

使用 Go 语言中的 Context 取消协程执行

使用 Go 语言中的 Context 取消协程执行 在 Go 语言中,协程(goroutine)是一种轻量级的线程,非常适合处理并发任务。然而,如何优雅地取消正在运行的协程是一个常见的问题。本文将通过一个具体的例子来展示如何使用 con…

【第三讲】Spring Boot 3.4.0 新特性详解:增强的配置属性支持

Spring Boot 3.4.0 版本在配置属性的支持上进行了显著增强,使得开发者能够更灵活地管理和使用应用程序的配置。新的特性包括对配置属性的改进、类型安全增强、以及对环境变量的更好支持。这些改进旨在提升开发效率和代码可读性,同时简化配置过程。本文将…

MySQL 启动失败问题分析与解决方案:`mysqld.service failed to run ‘start-pre‘ task`

目录 前言1. 问题背景2. 错误分析2.1 错误信息详解2.2 可能原因 3. 问题排查与解决方案3.1 检查 MySQL 错误日志3.2 验证 MySQL 配置文件3.3 检查文件和目录权限3.4 手动启动 MySQL 服务3.5 修复 systemd 配置文件3.6 验证依赖环境 4. 进一步优化与自动化处理结语 前言 在日常…

vue监听键盘事件

在实际应用中,很多时候我们需要监听键盘事件,在vue项目中该如何监听呢? 在mounted中新增监听事件 mounted() {this.dom document.getElementById("dialogHTTP");// 监听键盘抬起事件this.dom.addEventListener("keyup"…

安卓-碎片的使用入门

1.碎片(Fragment)是什么 Fragment是依赖于Activity的,不能独立存在的,是Activity界面中的一部分,可理解为模块化的Activity,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛. Fragment不能独立存在,必须…