如何利用多线程/并行处理提升Python爬虫脚本的并发运行效率?
解决方案:优化亚马逊爬虫的并行效率与CPU负载
一、用多线程替代多独立脚本实例
你的爬虫核心是IO密集型任务(大部分时间在等待网页加载、元素可见),而非CPU计算,多线程比多进程更适合——能避免多进程的上下文切换开销,大幅降低CPU占用,同时提升并行数量:
- 单进程多线程架构:一个Python进程内启动多个Chrome实例,每个线程管理一个driver,处理单条商品链接。
- 核心代码框架:
import threading import random import time from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from bs4 import BeautifulSoup import csv import queue def crawl_amazon(url, data_queue): # 配置Chrome优化参数(见下文) options = webdriver.ChromeOptions() options.add_argument('--headless=new') options.add_argument('--disable-gpu') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') options.add_argument('--disable-extensions') options.add_argument(f'user-agent={random.choice([ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" ])}') driver = webdriver.Chrome(options=options) try: driver.get(url) # 用WebDriverWait替代time.sleep,减少无效等待 WebDriverWait(driver, 12).until(EC.presence_of_element_located((By.ID, 'productTitle'))) soup = BeautifulSoup(driver.page_source, 'html.parser') title = soup.find(id='productTitle').get_text(strip=True) # 其他数据爬取逻辑... data_queue.put([url, title]) # 随机延迟,模拟人类操作 time.sleep(random.uniform(1.5, 4)) except Exception as e: print(f"爬取失败 {url}: {str(e)}") finally: driver.quit() def csv_writer_worker(data_queue): with open('amazon_data.csv', 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['商品链接', '商品标题']) while True: data = data_queue.get() if data is None: # 结束信号 break writer.writerow(data) data_queue.task_done() if __name__ == '__main__': # 替换为你的URL列表 target_urls = ['https://www.amazon.com/dp/B08N5WRWNW', ...] data_queue = queue.Queue(maxsize=50) # 启动单独的CSV写入线程(避免多线程写入冲突) writer_thread = threading.Thread(target=csv_writer_worker, args=(data_queue,)) writer_thread.start() # 控制并行线程数,先从15-20开始测试,观察CPU温度 max_threads = 18 active_threads = [] for url in target_urls: # 清理已完成的线程 active_threads = [t for t in active_threads if t.is_alive()] # 达到线程上限时等待 while len(active_threads) >= max_threads: time.sleep(0.5) active_threads = [t for t in active_threads if t.is_alive()] t = threading.Thread(target=crawl_amazon, args=(url, data_queue)) t.start() active_threads.append(t) # 等待所有爬虫线程完成 for t in active_threads: t.join() # 发送结束信号给写入线程 data_queue.put(None) writer_thread.join()
二、Chrome实例CPU优化配置
每个默认Chrome实例资源占用极高,添加以下参数可降低30%-50%的CPU负载,让你能同时运行更多实例:
--headless=new:启用新版无头模式,彻底关闭界面渲染,资源占用远低于旧版无头模式。--blink-settings=imagesEnabled=false:不需要爬取图片时禁用加载,大幅减少网络请求和CPU开销。--window-size=1280,720:指定固定窗口大小,避免Chrome动态调整窗口的额外消耗。--disable-background-timer-throttling:禁用后台定时器节流,提升页面加载稳定性的同时减少无效CPU唤醒。
三、IP封禁规避的并行策略
并行爬取极易触发亚马逊反爬,需配合以下规则:
- 线程数逐步递增:从15开始测试,观察是否出现验证码/403,找到CPU负载与反爬的平衡点。
- 代理IP池轮换:给每个线程分配不同代理,初始化Chrome时添加参数
options.add_argument('--proxy-server=http://ip:port')。 - 避免固定请求节奏:除了随机延迟,还可以随机调整等待元素的超时时间(比如8-15秒)。
四、CPU过热缓解额外措施
- 硬件层面:清理CPU散热器灰尘、更换硅脂,增加机箱风扇(台式机)或使用散热底座(笔记本)。
- 动态控速:监控CPU温度(Linux读
/sys/class/thermal/thermal_zone0/temp,Windows用psutil库),温度超过85℃时自动减少线程数,降至70℃以下再恢复。
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

