You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速基于BeautifulSoup的网页爬虫项目?

如何加速多URL网页爬虫的执行速度?

你的问题核心是串行请求导致的耗时过长——单个URL请求时,大部分时间都在等待网络响应(IO操作),串行循环会让每个请求都得等前一个完成才能开始,完全浪费了等待的时间。下面是几个针对性的优化方案:

1. 改用并发请求(最有效)

用多线程处理IO密集型任务,让多个URL请求同时进行,把等待时间重叠起来。Python的concurrent.futures.ThreadPoolExecutor可以轻松实现这一点,不需要复杂的线程管理:

import ssl
import bs4
from urllib.request import Request, urlopen
import json
from concurrent.futures import ThreadPoolExecutor

# 跳过SSL验证(注意:生产环境不建议这么做)
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

urls = ['https://www.tiffany.co.uk/jewelry/necklaces-pendants/tiffany-hardwear-graduated-link-necklace-63008966/', 
        'https://www.tiffany.co.uk/jewelry/necklaces-pendants/tiffany-t-smile-pendant-35189459/']

def get_price(url):
    req = Request(url, headers={'User-Agent': 'Mozilla/5.0'})
    webpage = urlopen(req, context=ctx).read()
    # 换成更快的lxml解析器(需要先pip install lxml)
    soup = bs4.BeautifulSoup(webpage, "lxml")
    data = json.loads(soup.find_all('script', {'type': 'application/ld+json'})[-1].get_text())
    return int(data['offers']['price'])

# 设置线程数,建议根据你的机器配置和网站反爬限制调整,比如4-8个
with ThreadPoolExecutor(max_workers=4) as executor:
    # 批量提交任务并获取结果
    results = executor.map(get_price, urls)
    for price in results:
        print(price)

2. 更换更快的HTML解析器

你当前用的html.parser是Python内置的,速度较慢。换成lxml解析器可以显著提升HTML解析的速度,只需要把bs4.BeautifulSoup(webpage, "html.parser")改成bs4.BeautifulSoup(webpage, "lxml"),记得先安装依赖:pip install lxml。

3. 复用HTTP连接(推荐改用requests库)

urllib的urlopen每次请求都会新建TCP连接,握手过程会额外耗时。改用requests库的Session对象可以复用连接,减少重复握手的开销,同时代码更简洁易读:

import bs4
import json
import requests
from concurrent.futures import ThreadPoolExecutor

# 创建会话,复用连接
session = requests.Session()
session.headers.update({'User-Agent': 'Mozilla/5.0'})
# 跳过SSL验证(生产环境谨慎使用)
session.verify = False

urls = ['https://www.tiffany.co.uk/jewelry/necklaces-pendants/tiffany-hardwear-graduated-link-necklace-63008966/', 
        'https://www.tiffany.co.uk/jewelry/necklaces-pendants/tiffany-t-smile-pendant-35189459/']

def get_price(url):
    response = session.get(url)
    soup = bs4.BeautifulSoup(response.text, "lxml")
    data = json.loads(soup.find_all('script', {'type': 'application/ld+json'})[-1].get_text())
    return int(data['offers']['price'])

with ThreadPoolExecutor(max_workers=4) as executor:
    results = executor.map(get_price, urls)
    for price in results:
        print(price)

4. 其他小优化

  • 设置超时时间:给请求加上超时,避免某个请求卡住整个程序,比如urlopen(req, context=ctx, timeout=10)或者session.get(url, timeout=10)。
  • 避免重复解析不必要的内容:如果只需要提取JSON数据,可以不用完全解析HTML,直接用正则匹配application/ld+json的内容,减少BeautifulSoup的工作量(不过可读性会下降)。
  • 注意反爬限制:不要设置过高的并发数,避免被网站封禁IP,建议先测试小批量URL,观察网站的响应情况。

内容的提问来源于stack exchange,提问作者Seedizens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 14:30:51