Python多线程网页爬取报错及线程池参数设置求助
问题解决与线程池说明
1. 报错BrokenProcessPool的原因与修复
你的代码存在几个关键问题导致了该错误:
- 缺失必要导入:代码里用到
BeautifulSoup、requests、json但未导入,运行时会触发未捕获异常,直接导致线程池崩溃。 - 方法调用错误:
multiprocessing.dummy.ThreadPool没有process_map方法,正确调用应为pool.map(AuM_sdg, codes)。 - 空except吞掉异常:
except:会捕获所有错误且无处理逻辑,一旦单个任务抛出致命异常,整个池会直接失效。
修复后的代码示例:
import pandas as pd import requests from bs4 import BeautifulSoup import json from multiprocessing.dummy import Pool as ThreadPool codes = [1829, 1321, 6536, 6426, 558, 380, 1850, 4923, 5961, 4925] def AuM_sdg(code_sdg): try: code_sdg = str(code_sdg) url = f"https://www.quantalys.com/espace/{code_sdg}" # 添加请求头避免被网站拦截 headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"} response = requests.get(url, headers=headers, timeout=10) response.raise_for_status() # 触发HTTP错误异常 soup = BeautifulSoup(response.content, "html.parser") input_elem = soup.select_one("#chartEncours8a input") if not input_elem: print(f"未找到目标元素,code: {code_sdg}") return None data = json.loads(input_elem["value"]) df = pd.DataFrame(data['dataProvider']) df['unit'] = data['valueAxes'][0]['unit'] return df except requests.exceptions.RequestException as e: print(f"请求错误,code: {code_sdg}, 错误信息: {str(e)}") return None except (KeyError, json.JSONDecodeError) as e: print(f"数据解析错误,code: {code_sdg}, 错误信息: {str(e)}") return None except Exception as e: print(f"未知错误,code: {code_sdg}, 错误信息: {str(e)}") return None pool = ThreadPool(8) results = pool.map(AuM_sdg, codes) # 关闭并等待池完成所有任务 pool.close() pool.join() # 过滤无效结果并合并 valid_results = [df for df in results if df is not None] final_df = pd.concat(valid_results, ignore_index=True)
2. ThreadPool(8)的含义与合理设置
- 数字8的含义:表示创建一个包含8个工作线程的线程池,同一时间最多有8个线程并行执行
AuM_sdg函数处理任务。 - 合理设置建议:
- 网页爬取属于IO密集型任务(大部分时间在等待网络响应),线程数可设置为CPU核心数的2-4倍,或根据目标网站反爬策略调整。
- 不要设置过大(比如超过20),否则易触发网站反爬机制(如IP被封),也会耗尽本地网络资源。
- 建议从5-10的数值开始测试,观察执行速度和网站响应情况后再调整到合适值。
内容的提问来源于stack exchange,提问作者Jacques
相关产品推荐
相关产品推荐

