Python多进程未提升网页金属价格爬虫运行效率的问题咨询
问题分析与解决方案
哦,我一眼就看到问题出在哪了——你根本没真正用上多进程并行!
核心错误点
你当前的代码有两个致命的串行执行问题:
- 提前执行了scraper函数:创建进程时写的是
p1 = Process(target=scraper(url,"alu")),这里你直接调用了scraper(url,"alu"),这会在主进程里立刻执行完整个函数,然后把函数的返回值(也就是None)传给target参数。等于所有scraper操作都是在主进程串行完成的,多进程完全没起作用。 - 提前串行请求了所有URL:你在创建每个进程前都先执行了
requests.get(url),这一步也是完全串行的,请求时间已经占了大部分耗时,后面的多进程自然没法提速。
另外,用全局变量存储价格在多进程里也有问题——每个子进程有独立的内存空间,全局变量的修改不会共享到主进程,最后你可能拿不到正确的结果。
修正后的代码
我帮你调整了代码,让多进程真正并行工作,同时解决全局变量的问题:
第一步:重构scraper函数
把requests.get移到函数内部,让每个子进程自己处理请求和解析,同时用队列返回结果:
from bs4 import BeautifulSoup import requests from multiprocessing import Process, Queue def scraper(url, metal, result_queue): # 每个进程独立发起HTTP请求 response = requests.get(url) soup = BeautifulSoup(response.content, "html.parser") samples = soup.find_all("td", style="text-align:center;white-space:nowrap;border-left:solid black 1px") prices = [] for a in samples: for b in a: # 先判断是否是字符串类型,避免遍历到标签对象报错 if isinstance(b, str) and b.startswith("$"): cleaned_price = b.replace(" ", "").replace("$", "") try: prices.append(int(cleaned_price)) except ValueError: # 处理非数字的异常情况,避免程序崩溃 continue # 将结果存入队列,供主进程收集 result_queue.put((metal, prices))
第二步:正确使用多进程
创建进程时,target传入函数本身,参数通过args传递,同时用队列收集所有子进程的结果:
if __name__ == '__main__': # 用队列实现多进程间的安全通信(替代全局变量) result_queue = Queue() # 把URL和对应金属名整理成列表,方便循环创建进程 task_list = [ ("https://www.alumeco.dk/viden-og-teknik/metalpriser/aluminiumpriser?s=0", "alu"), ("https://www.alumeco.dk/viden-og-teknik/metalpriser/kobber?s=0", "kobber"), ("https://www.alumeco.dk/viden-og-teknik/metalpriser/metal-priser-mp58?s=0", "messing"), ("https://www.alumeco.dk/viden-og-teknik/metalpriser/zink?s=0", "zink"), ] processes = [] for url, metal in task_list: # target传函数对象,args传函数需要的参数 process = Process(target=scraper, args=(url, metal, result_queue)) processes.append(process) process.start() # 等待所有子进程执行完成 for process in processes: process.join() # 从队列中取出所有结果,整理成字典 final_results = {} while not result_queue.empty(): metal_name, price_list = result_queue.get() final_results[metal_name] = price_list # 打印最终结果 print("抓取到的金属价格:", final_results)
效果说明
修改后,4个HTTP请求和HTML解析操作会在你的4核4线程CPU上并行执行,运行时间应该会降到原来的1/4左右(也就是3秒上下),符合你预期的提速效果。
内容的提问来源于stack exchange,提问作者Elias Larsen
相关产品推荐
相关产品推荐

