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

如何优化我的Web Scraping程序以提升运行效率?

爬虫性能优化方案

你的爬虫扫描43篇文章耗时26秒,核心瓶颈集中在串行网络请求、重复数据库IO和冗余的邮件连接操作上,以下是针对性的优化方案:

1. 并行处理网络请求

当前串行请求每篇文章的方式,会把大量时间浪费在等待网络响应上。改用多线程并行请求,能大幅压缩总耗时(网络IO场景下,多线程比多进程更高效):

from concurrent.futures import ThreadPoolExecutor

def fetch_article(url):
    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'
    }
    try:
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        return url, response.text
    except Exception as e:
        print(f"请求失败 {url}: {e}")
        return url, None

# 并行请求所有文章,max_workers根据网站限制调整,建议5-10
with ThreadPoolExecutor(max_workers=8) as executor:
    results = executor.map(fetch_article, articles)

# 批量处理返回结果
for url, html in results:
    if not html:
        continue
    Asoup = BeautifulSoup(html, 'lxml')
    # 后续解析逻辑...

2. 数据库操作优化

2.1 给URL字段添加索引

当前查询SELECT * FROM artikler WHERE url=?是全表扫描,给URL加索引能让查询速度提升数倍:

# 建表时同步加索引,若表已存在单独执行这条
try:
    c.execute("CREATE TABLE artikler (tittel text, dato text, url text, UNIQUE(url))")
    c.execute("CREATE INDEX IF NOT EXISTS idx_url ON artikler(url)")
except:
    pass

2.2 减少数据库交互次数

  • 预先查询所有已爬取的URL存入集合,避免循环中反复查库;
  • 积累多条插入数据后批量提交,减少commit()的IO开销:
# 预先获取所有已存在的URL
c.execute("SELECT url FROM artikler")
existing_urls = {row[0] for row in c.fetchall()}
insert_data = []

# 循环中判断并积累数据
if url not in existing_urls and relevant:
    insert_data.append((title, date, url))

# 批量插入
if insert_data:
    c.executemany("INSERT INTO artikler VALUES (?, ?, ?)", insert_data)
    conn.commit()

3. 关键词匹配逻辑优化

原代码的循环逻辑存在错误(只要遇到不匹配的关键词就会覆盖relevant为False),同时可以用更高效的方式判断匹配:

# 转成集合加速in操作,合并标题和内容一次检查
keywords_set = set(keywords)
text_to_check = title + " " + caption
# 只要有一个关键词匹配就标记为相关
relevant = any(word in text_to_check for word in keywords_set)

# 若关键词包含特殊字符,用正则一次匹配更可靠
import re
pattern = re.compile('|'.join(re.escape(word) for word in keywords))
relevant = pattern.search(text_to_check) is not None

4. 复用SMTP连接

当前每次发邮件都重新建立SMTP连接,连接建立的开销远大于发送本身,改为只建立一次连接:

# 在所有循环外建立连接
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
    smtp.login("your_email@gmail.com", "your_app_password")  # Gmail需用应用专用密码
    
    # 循环处理文章,需要发邮件时直接复用连接
    if url not in existing_urls and relevant:
        # ... 数据库插入逻辑 ...
        smtp.send_message(msg)

5. 其他辅助优化

  • 页面缓存:用requests-cache缓存已爬取页面,避免重复请求相同内容:
    import requests_cache
    requests_cache.install_cache('news_cache', expire_after=3600)  # 缓存1小时
    
  • 缩小解析范围:解析时只提取需要的HTML片段,减少BeautifulSoup的处理量:
    # 比如只解析header部分
    header_html = Asoup.find('header', class_='entry-header')
    if header_html:
        # 从header_html中提取标题等内容
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 03:30:55