发布时间:2026/7/14 17:51:17
影刀RPA 多线程基础:并发采集入门 影刀RPA 多线程基础并发采集入门署名林焱什么情况用什么RPA采集100个网页单线程一个个打开要30分钟。如果同时开5个线程6分钟就跑完了。多线程能显著提升IO密集型任务效率。场景推荐方式特点网页批量采集threading 队列简单易用CPU密集型计算multiprocessing绕过GIL限制大量并发请求ThreadPoolExecutor线程池管理怎么做一基础多线程importthreadingimporttime# 单线程对比deffetch_page(url):模拟采集一个网页print(f开始采集:{url})time.sleep(2)# 模拟网络请求耗时print(f完成采集:{url})returnf{url}的内容urls[https://example.com/page1,https://example.com/page2,https://example.com/page3,https://example.com/page4,https://example.com/page5,]# 单线程约10秒 print( 单线程 )starttime.time()results[]forurlinurls:results.append(fetch_page(url))print(f耗时:{time.time()-start:.1f}秒)# 多线程约2秒 print(\n 多线程 )starttime.time()threads[]results[None]*len(urls)# 预分配结果列表defworker(index,url):results[index]fetch_page(url)fori,urlinenumerate(urls):tthreading.Thread(targetworker,args(i,url))threads.append(t)t.start()# 等待所有线程完成fortinthreads:t.join()print(f耗时:{time.time()-start:.1f}秒)二线程池推荐拼多多店群自动化报活动上架fromconcurrent.futuresimportThreadPoolExecutor,as_completedimporttimedeffetch_page(url):采集网页time.sleep(1)# 模拟请求return{url:url,status:200,data:f{url}的内容}urls[fhttps://example.com/page{i}foriinrange(1,21)]# 使用线程池max_workers5# 最多5个线程同时运行results[]withThreadPoolExecutor(max_workersmax_workers)asexecutor:# 提交所有任务![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/73c282530e3f4f16a0b780322253ab24.png#pic_center)future_to_url{executor.submit(fetch_page,url):urlforurlinurls}# 按完成顺序获取结果forfutureinas_completed(future_to_url):urlfuture_to_url[future]try:resultfuture.result()results.append(result)print(f完成:{url})exceptExceptionase:print(f失败:{url}, 错误:{e})print(f\n共完成{len(results)}个任务)三线程安全的队列importthreadingimportqueueimporttime# 任务队列task_queuequeue.Queue()result_queuequeue.Queue()# 填充任务urls[fhttps://example.com/page{i}foriinrange(1,21)]forurlinurls:task_queue.put(url)defworker(worker_id):工作线程whileTrue:try:# 非阻塞获取任务超时退出urltask_queue.get(timeout1)exceptqueue.Empty:break# 执行任务try:time.sleep(0.5)# 模拟采集resultf[线程{worker_id}] 采集完成:{url}result_queue.put({url:url,status:success,data:result})exceptExceptionase:result_queue.put({url:url,status:error,error:str(e)})finally:task_queue.task_done()# 启动多个工作线程num_workers5threads[]foriinrange(num_workers):tthreading.Thread(targetworker,args(i,))t.start()threads.append(t)# 等待所有任务完成task_queue.join()# 收集结果results[]whilenotresult_queue.empty():results.append(result_queue.get())print(f完成{len(results)}个任务)forrinresults[:5]:print(r[data])四线程安全的数据操作importthreading# 线程安全的计数器classSafeCounter:def__init__(self):self._lockthreading.Lock()self._count0defincrement(self):withself._lock:self._count1returnself._countpropertydefvalue(self):withself._lock:returnself._count# 线程安全的列表classSafeList:def__init__(self):self._lockthreading.Lock()self._data[]defappend(self,item):withself._lock:self._data.append(item)defget_all(self):withself._lock:returnlist(self._data)# 使用counterSafeCounter()resultsSafeList()defworker(url):numcounter.increment()results.append(f第{num}个任务:{url})threads[threading.Thread(targetworker,args(furl{i},))foriinrange(10)]fortinthreads:t.start()fortinthreads:t.join()print(f计数:{counter.value})foriteminresults.get_all():print(item)完整流程并发采集管理器fromconcurrent.futuresimportThreadPoolExecutor,as_completedimportthreadingimporttimefromdatetimeimportdatetime# yd_input: urls, max_workers, delayurlsyd_input.get(urls,[])max_workersyd_input.get(max_workers,5)delayyd_input.get(delay,0.5)# 统计stats{total:len(urls),success:0,failed:0,start_time:datetime.now().strftime(%Y-%m-%d %H:%M:%S)}stats_lockthreading.Lock()results[]results_lockthreading.Lock()deffetch_url(url):采集单个URLtry:time.sleep(delay)# 控制请求频率# 这里放实际的采集逻辑# 例如用requests获取网页、解析数据等importrequests resprequests.get(url,timeout15,headers{User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64)})ifresp.status_code200:result{url:url,status:success,code:resp.status_code,length:len(resp.text),timestamp:datetime.now().strftime(%H:%M:%S)}withstats_lock:stats[success]1withresults_lock:results.append(result)returnresultelse:raiseException(fHTTP{resp.status_code})exceptExceptionase:withstats_lock:stats[failed]1result{url:url,status:error,error:str(e),timestamp:datetime.now().strftime(%H:%M:%S)}withresults_lock:results.append(result)returnresult# 执行并发采集start_timetime.time()withThreadPoolExecutor(max_workersmax_workers)asexecutor:futures{executor.submit(fetch_url,url):urlforurlinurls}completed0forfutureinas_completed(futures):completed1urlfutures[future]try:resultfuture.result()status_icon✓ifresult[status]successelse✗print(f{status_icon}[{completed}/{len(urls)}]{url})exceptExceptionase:print(f✗ [{completed}/{len(urls)}]{url}:{e})elapsedtime.time()-start_time stats[end_time]datetime.now().strftime(%Y-%m-%d %H:%M:%S)stats[elapsed]f{elapsed:.1f}秒print(f\n 采集完成 )print(f总计:{stats[total]}, 成功:{stats[success]}, 失败:{stats[failed]})print(f耗时:{elapsed:.1f}秒, 平均:{elapsed/len(urls):.2f}秒/个)yd_output{status:ok,stats:stats,results:results}有什么坑坑一多线程共享变量导致数据错乱现象多个线程同时写同一个列表结果列表长度不对或某些数据丢失。原因Python列表的append操作不是原子操作多线程同时写会导致数据覆盖。解决用锁保护共享数据importthreading# 错误不加锁# results []# def worker(url):# results.append(url) ❌ 多线程同时append可能丢数据# 正确用锁results[]lockthreading.Lock()defworker(url):withlock:results.append(url)# ✓ 同一时刻只有一个线程能写# 更好的方案用Queue线程安全importqueue result_queuequeue.Queue()defworker(url):result_queue.put(url)# ✓ Queue自带线程安全坑二线程数过多反而变慢现象把max_workers设为100结果比5个线程还慢。原因线程太多导致频繁的上下文切换开销大于并行收益。另外大量并发请求可能触发网站反爬导致请求被拒绝后重试。解决合理设置线程数TEMU店群矩阵自动化运营核价报活动# IO密集型任务网络请求线程数 CPU核数 × 2~5importos cpu_countos.cpu_count()# CPU核数optimal_workersmin(cpu_count*3,20)# 推荐3-20个线程# 不要无脑设大# max_workers 100 ❌ 太多反而慢# 根据目标网站承受能力调整# 小网站3-5个线程# 大网站10-20个线程# API接口看API的rate limit要求坑三主线程退出导致子线程中断现象主线程跑完了子线程还没完成就被强制退出结果不完整。原因默认子线程是守护线程daemonFalse主线程会等子线程完成。但如果设了daemonTrue主线程退出时子线程会被杀掉。解决确保正确等待子线程完成importthreading# 方案1用join等待推荐threads[]foriinrange(5):tthreading.Thread(targetworker,args(i,))t.start()threads.append(t)fortinthreads:t.join()# 等待每个线程完成print(所有线程完成)# 方案2用ThreadPoolExecutor自动等待fromconcurrent.futuresimportThreadPoolExecutorwithThreadPoolExecutor(max_workers5)asexecutor:futures[executor.submit(worker,i)foriinrange(5)]# with块结束时自动等待所有任务完成# 错误设为daemonTrue后不等待# t threading.Thread(targetworker, daemonTrue)# t.start()# # 不join主线程退出时子线程被杀 ❌坑四线程中的异常不会自动传播到主线程现象子线程报错了但主线程不知道以为全部成功。原因子线程的异常不会自动抛到主线程需要主动检查。解决用Future.result()获取异常或用try-except记录fromconcurrent.futuresimportThreadPoolExecutor,as_completeddefworker(url):iferrorinurl:raiseValueError(模拟错误)returnfsuccess:{url}urls[url1,error_url,url3]withThreadPoolExecutor(max_workers3)asexecutor:futures{executor.submit(worker,url):urlforurlinurls}forfutureinas_completed(futures):urlfutures[future]try:![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/768973b01eb040f38abbd2c293528c22.png#pic_center)# future.result()会重新抛出子线程中的异常resultfuture.result()print(f✓{url}:{result})exceptExceptionase:print(f✗{url}:{e})# 捕获子线程异常# 如果不用Future需要在worker函数内部catch异常defsafe_worker(url):try:# 实际逻辑returndo_work(url)exceptExceptionase:return{url:url,error:str(e)}# 返回错误信息而不是抛出

相关新闻

2026/7/14 17:51:17

从ChatGPT到AGI:2026年AI大模型的终极追问与未来幻想

国内用户访问提示:由于网络限制,OpenAI官网及Anthropic官网在国内无法直接访问。国内用户可通过镜像平台AIGCBAR体验ChatGPT、Claude等主流AI模型。该平台内置Auto模式与Thinking模式,思考程度提供标准和深度两档可选,支持国内邮箱…

2026/7/14 17:51:17

TMC7300+STM32L4S5ZI驱动有刷电机方案解析

1. 为什么选择TMC7300STM32L4S5ZI组合驱动有刷电机 有刷直流电机作为最传统的电机类型,至今仍在各类消费电子、工业设备和自动化系统中广泛应用。但要让这类电机实现精准稳定的转速控制,传统的H桥驱动方案往往面临效率低、发热大、响应慢等问题。这正是T…

2026/7/14 17:51:17

企业AI Agent与数据湖融合架构设计与优化实践

1. 企业AI Agent与数据湖的融合趋势最近两年,企业AI Agent正在从单纯的对话机器人向具备复杂决策能力的智能体演进。我在为三家制造业客户部署AI Agent时发现,传统的数据管道架构已经难以满足实时决策需求。某汽车零部件供应商的质检AI Agent需要同时处理…

2026/7/14 18:46:20

基于TPS61170与PIC18F65K40的高效DC-DC升压转换设计

1. 项目背景与核心器件选型在工业控制、医疗设备和实验室仪器等领域,经常需要将低压直流电源转换为高压直流电源。传统方案采用分立元件搭建,存在效率低、体积大、稳定性差等问题。而采用专用DC-DC升压转换芯片配合微控制器,能实现更高效可靠…

2026/7/14 18:46:20

Large Language Model-assisted Autonomous Vehicle Recovery from Immobilization

一、文章主要内容总结 该研究针对自动驾驶汽车(AV)在复杂交通场景中易陷入停滞( immobilization)、现有恢复方案(远程干预成本高、人工接管适用性有限)存在缺陷的问题,提出了一种基于大语言模型(LLM)的恢复框架StuckSolver。 StuckSolver设计为插件式附加模块,无需…

2026/7/14 18:46:20

Windows系统MBR磁盘分区详解与实战指南

1. Windows系统MBR磁盘分区基础解析MBR(Master Boot Record)是Windows系统沿用数十年的传统磁盘分区方案。作为系统启动的核心数据结构,MBR位于磁盘的第一个扇区(512字节),包含引导加载程序和分区表信息。在…

2026/7/14 18:46:20

微信小程序中药材识别系统开发与优化实践

1. 项目概述:中药材识别科普系统的价值与定位在移动互联网时代,微信小程序以其无需安装、即用即走的特性,成为知识传播的理想载体。这个基于微信小程序的中药材识别科普系统,瞄准了中医药文化传承与大众健康需求之间的断层。想象一…

2026/7/14 18:46:20

惠普暗影精灵终极性能解锁:OmenSuperHub完整使用指南

惠普暗影精灵终极性能解锁:OmenSuperHub完整使用指南 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub OmenSuper…

2026/7/14 18:41:20

创建账户和组

目录; 1.创建账户 1.1.命令行 1.2.计算机管理 2.创建组 2.1.命令行 2.2.计算机管理 3.附; 3.1.账户组中添加账户 3.1.1.命令行 3.1.2.计算机管理 4.本节命令 在多人同时使用一台电脑共用一个系统是创建多和账户是个不错的选择,目…

2026/7/14 12:47:32

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾在网易云音乐下载了心爱的歌曲&#…

2026/7/13 14:26:14

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境随着新能源汽车行业的快速发展,充电通信协议的标准化和测试验证变得尤为重要。GB/T 27930-2023作为中国智能充电协议的最新版本,对充电机与电动汽车之间的通信提出了更严格…

2026/7/14 18:30:06

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡 【免费下载链接】rtl8852be Realtek Linux WLAN Driver for RTL8852BE 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8852be 还在为Linux系统无法识别RTL8852BE Wi-Fi 6网卡而烦恼吗?&#x1f…

2026/7/14 0:04:21

5分钟掌握足球PBR材质制作:Photoshop与Unity高效工作流

1. 项目概述:为什么是足球PBR材质?在游戏开发,尤其是体育竞技类游戏的制作中,一个看起来“对味”的足球,往往比我们想象中更重要。它不仅是赛场上的核心道具,更是玩家视觉焦点和沉浸感的重要来源。一个塑料…

2026/7/14 0:04:21

ChatGPT联网搜索失败,92%开发者误判为网络问题——真实根因竟是LLM推理会话上下文污染导致Search Agent进程静默退出(含strace复现脚本)

更多请点击: https://intelliparadigm.com 第一章:ChatGPT 联网搜索失败 当 ChatGPT 的联网搜索功能无法正常工作时,用户常遇到“搜索不可用”“未连接到互联网”或空白响应等现象。该问题并非模型本身缺陷,而是由权限配置、网络…

2026/7/14 12:47:31

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…