使用Python+BeautifulSoup爬取Autotrader:无类/ID的UL元素遍历难题
解决Autotrader无标识UL/LI参数提取问题
看起来你已经搞定了标题和价格的抓取,卡在无类名/ID的UL元素遍历上太正常了——这类动态生成的列表确实容易让人头疼。我来分享几个实用方案,帮你把LI里的参数规整到列表并映射到Excel字段:
1. 先定位车辆卡片容器,再嵌套查找UL
Autotrader的车辆信息通常都包裹在有明确标识的卡片容器里(比如带data-testid="listing-card"属性的div),先抓这个容器,再在里面找目标UL,就不会误抓其他无关的UL了。用BeautifulSoup的话,代码可以这么写:
from bs4 import BeautifulSoup import requests import pandas as pd import time # 加请求头模拟浏览器,避免被反爬拦截 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" } # 示例列表页URL(替换成你要爬的地址) url = "https://www.autotrader.co.uk/car-search?..." response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, "html.parser") # 抓取所有车辆卡片 vehicle_cards = soup.find_all("div", attrs={"data-testid": "listing-card"}) # 准备存储数据的列表 car_data = [] for card in vehicle_cards: # 提取你已经搞定的标题和价格 title = card.find("h3", attrs={"data-testid": "listing-title"}).text.strip() price = card.find("span", attrs={"data-testid": "listing-price"}).text.strip() # 定位目标UL:优先找卡片内的参数列表UL(如果是卡片内唯一的UL,直接用find("ul")即可) # 如果有多个UL,用属性模糊匹配更精准 spec_ul = card.find("ul", class_=lambda x: x and "listing-key-specs" in x) # 遍历UL下的LI,提取参数文本 specs = [] if spec_ul: specs = [li.text.strip() for li in spec_ul.find_all("li")] # 将参数映射到Excel字段:Autotrader的LI通常按「年份、里程、变速箱、燃料类型」顺序排列 car_info = { "车辆标题": title, "价格": price, "生产年份": specs[0] if len(specs) >=1 else None, "行驶里程": specs[1] if len(specs) >=2 else None, "变速箱类型": specs[2] if len(specs) >=3 else None, "燃料类型": specs[3] if len(specs) >=4 else None } car_data.append(car_info) # 加延迟避免触发反爬 time.sleep(1.5) # 导出到Excel表格 df = pd.DataFrame(car_data) df.to_excel("autotrader_vehicle_data.xlsx", index=False)
2. 处理参数格式不统一的情况
有时候LI里的内容可能顺序混乱或包含冗余信息,这时候可以用正则表达式提取关键内容:
import re # 从LI文本中提取年份 def extract_year(text): match = re.search(r"\b\d{4}\b", text) return match.group() if match else None # 提取里程数(去除逗号和单位) def extract_mileage(text): match = re.search(r"(\d{1,3}(?:,\d{3})*) miles", text) return match.group(1).replace(",", "") if match else None # 在循环里替换对应字段 car_info = { "车辆标题": title, "价格": price, "生产年份": extract_year(specs[0]) if specs else None, "行驶里程": extract_mileage(specs[1]) if len(specs)>=2 else None, # 其他字段同理处理 }
3. 避坑提示
- Autotrader对频繁请求敏感,一定要加延迟,爬大量数据时建议用代理IP轮换
- 如果遇到动态加载的内容,可能需要用
Selenium或Playwright模拟浏览器渲染,而不是单纯用requests - 尽量不要一次性爬太多页面,分批次抓取更安全
这样处理后,你就能顺利把UL里的LI参数规整到对应的Excel字段里了,亲测有效!
内容的提问来源于stack exchange,提问作者Csongor
相关产品推荐
相关产品推荐

