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

爬虫程序无报错却运行耗时过长,疑似循环问题求排查

爬虫性能优化方案

你的爬虫耗时过长主要集中在DataFrame操作效率低下、串行请求等待、冗余代码这几个方面,以下是具体优化点和修改后的代码:

核心问题分析与优化

  • 频繁调用DataFrame.append()是性能杀手:每次append都会生成新的DataFrame对象,循环中多次执行会产生大量内存拷贝,随着数据量增大,耗时呈指数级上升。建议用列表存储数据字典,最后一次性转换为DataFrame。
  • html.parser解析速度慢:BeautifulSoup默认的html.parser比lxml解析器慢很多,换成lxml能大幅提升页面解析速度(需先安装lxml库:pip install lxml)。
  • 冗余的网络请求:代码开头的requests.get(request_url)和BeautifulSoup解析完全没有被使用,属于无效请求,直接删除。
  • 低效的终止判断逻辑:if '<div class = "noCar">' in str(page_info)这种把DataFrame转成字符串搜索的方式效率极低,应该在页面解析阶段直接判断是否存在无数据的标识元素。
  • 串行请求等待时间长:每次请求都要等待响应后才能发起下一次,改用requests.Session复用TCP连接,能减少握手开销,降低等待时间。

修改后的代码

import requests
from bs4 import BeautifulSoup
import pandas as pd
from requests.adapters import HTTPAdapter

# 复用TCP连接,减少握手开销
session = requests.Session()
session.mount('http://', HTTPAdapter(max_retries=3))
session.mount('https://', HTTPAdapter(max_retries=3))

headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
}

def get_info(page_url):
    try:
        html = session.get(page_url, headers=headers, timeout=10)
        html.raise_for_status()  # 捕获HTTP错误
        soup = BeautifulSoup(html.text, 'lxml')  # 改用lxml解析器
        
        # 先判断是否存在无数据标识
        if soup.find('div', class_='noCar'):
            return []
        
        temp = soup.find('div', class_='tslb_b')
        if not temp:
            return []
        
        tr_list = temp.find_all('tr')
        data_list = []
        for tr in tr_list:
            td_list = tr.find_all('td')
            if len(td_list) == 8:  # 确保字段数量正确
                data_dict = {
                    'id': td_list[0].text.strip(),
                    'brand': td_list[1].text.strip(),
                    'car_model': td_list[2].text.strip(),
                    'type': td_list[3].text.strip(),
                    'desc': td_list[4].text.strip(),
                    'problem': td_list[5].text.strip(),
                    'datetime': td_list[6].text.strip(),
                    'status': td_list[7].text.strip()
                }
                data_list.append(data_dict)
        return data_list
    except Exception as e:
        print(f"获取页面{page_url}失败: {str(e)}")
        return []

request_url = input("请输入目标URL: ")

result_data = []
current_page = 1

while True:
    # 构造分页URL(注意:原代码的[:48]拼接逻辑需根据实际URL确认是否正确)
    page_url = request_url[:48] + str(current_page) + "d&cb=0&csb=0&cs=0&cm=0&ba=0&qt=0&z=0&zs=0&f=0&nt=0&fu=0&qts=0&wd=%e5%a4%87%e8%83%8e"
    
    page_data = get_info(page_url)
    
    if not page_data:
        break
    
    result_data.extend(page_data)
    current_page += 1
    
    if current_page > 100:  # 限制最多爬100页
        break

# 最后一次性转换为DataFrame
result = pd.DataFrame(result_data, columns=['id', 'brand', 'car_model', 'type', 'desc', 'problem', 'datetime', 'status'])
result.to_csv('result.csv', index=False, encoding='utf-8-sig')

额外优化建议

  • 如果爬取页数较多,可引入异步请求库aiohttp,同时发起多个请求,将总耗时压缩到接近单页请求时间。
  • 给请求添加随机延迟(如time.sleep(random.uniform(0.5, 1.5))),避免触发网站反爬机制,同时减少服务器压力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:54:58