如何在Python中并行运行同一函数以实现多链接同时爬取
解决Python爬虫串行爬取速度慢的问题:多进程并行方案
嘿,我来帮你搞定这个多进程爬取的问题!面对5000个链接的串行爬取,确实会因为大部分时间都在等待网络响应而浪费效率,用多进程并行处理能帮你把速度提上来。
核心思路
串行爬取时,单个进程每次只处理一个链接,大部分时间处于等待状态。多进程可以同时发起多个请求,把等待的时间利用起来,大幅提升整体爬取效率。
具体实现方案
我们可以用Python标准库中的concurrent.futures.ProcessPoolExecutor来实现多进程并行,它的API非常简洁,容易上手。
步骤1:改造爬取函数
首先把原来遍历整个链接列表的函数,改成单个链接处理函数——每个进程负责处理一个链接:
import requests def fetch_link(link): try: # 发起请求 response = requests.get(link, timeout=5) # --- 这里写你的爬取逻辑(解析数据、保存结果等)--- # 示例:打印成功信息 print(f"✅ 成功获取链接: {link}") # 如果需要返回结果,可以在这里return处理后的数据 return {"link": link, "status": response.status_code} except requests.exceptions.RequestException as e: # 处理请求异常(超时、连接失败等) print(f"❌ 获取链接失败 {link}: {str(e)}") return {"link": link, "status": "failed", "error": str(e)}
步骤2:用进程池批量处理链接
接下来创建进程池,把链接列表交给进程池并行处理:
from concurrent.futures import ProcessPoolExecutor if __name__ == "__main__": # 你的5000个链接列表 links = ["http://example.com", "http://test.com", ...] # 设置进程池大小:建议根据CPU核心数调整(比如核心数的2-4倍),同时别超过目标网站的承受能力 max_workers = 8 # 创建进程池并执行任务 with ProcessPoolExecutor(max_workers=max_workers) as executor: # 用map方法把每个链接分配给进程池中的进程处理 results = list(executor.map(fetch_link, links)) # 可以在这里统一处理所有结果(比如保存到文件/数据库) print(f"\n📊 爬取完成,共处理 {len(results)} 个链接")
关键注意事项
if __name__ == "__main__":必须加:这是Windows系统下多进程运行的必要条件,避免进程重复启动的问题。- 合理设置
max_workers:不要盲目设太大,否则可能导致目标网站触发反爬机制(封禁IP),也会消耗本地过多资源。建议从8-16开始测试,根据实际情况调整。 - 反爬应对:并行爬取容易被网站识别为爬虫,建议添加请求头(比如
User-Agent模拟浏览器)、随机延迟(可以在fetch_link里加time.sleep(random.uniform(0.5, 2))),必要时使用代理池。 - IO密集型任务可选线程池:如果你的爬取逻辑主要是等待网络响应(IO密集型),用
ThreadPoolExecutor(把ProcessPoolExecutor替换成它)的开销更小,效率也差不多,因为线程切换成本比进程低。
备选方案:用multiprocessing.Pool
如果你习惯用更底层的multiprocessing模块,也可以这样写:
from multiprocessing import Pool import requests def fetch_link(link): # 和上面的fetch_link函数逻辑一致 pass if __name__ == "__main__": links = [...] with Pool(processes=8) as pool: results = pool.map(fetch_link, links)
这样应该能大幅提升你的爬取速度啦!记得根据目标网站的情况调整并发数,别太猛导致被封禁哦~
内容的提问来源于stack exchange,提问作者Soham Chakraborty
相关产品推荐
相关产品推荐

