Python+BeautifulSoup eBay爬虫未抓取全部页面数据问题求助
eBay爬虫数据量不符问题排查与解决
问题背景
我是一名新手开发者,受公司委托开发eBay网页爬虫以协助CFO查找所需库存商品。当前已实现多页面抓取功能,但Pandas DataFrame加载后结果数量与预期不符:设置为每页抓取60条、共10页,预期获取约600条数据,但实际仅得到300条。已添加10秒sleep仍未解决问题。
现有代码
import time import requests import re import pandas as pd from bs4 import BeautifulSoup data = [] # searchkey = input() # base_url = 'https://www.ebay.com/sch/i.html?_nkw=' + searchkey + '&_sacat=0&_ipg=240 base_url = 'https://www.ebay.com/sch/i.html?_nkw=ipads&_sacat=0&_ipg=60' for page in range(1, 11): page_url = base_url + '&_pgn=' + str(page) time.sleep(10) soup = BeautifulSoup(requests.get(page_url).text) for links in soup.select('.srp-results li.s-item'): item_url = links.a['href'] soup2 = BeautifulSoup(requests.get(item_url).text) for content in soup2.select('.lsp-c'): data.append({ 'item_name' : content.select_one('h1.x-item-title__mainTitle > span').text, 'name' : 'Click Here to see Webpage', 'url' : str(item_url), 'hot' : "Hot!" if content.select_one('div.d-urgency') else "", 'condition' : content.select_one('span.clipped').text, 'price' : content.select_one('div.x-price-primary > span').text, 'make offer' : 'Make Offer' if content.select_one('div.x-offer-action') else str('Contact Seller') }) df = pd.DataFrame(data) df['link'] = df['name'] + '#' + df['url'] def make_clickable_both(val): name, url = val.split('#') return f'<a href="{url}">{name}</a>' df2 = df.drop(columns=['name', 'url']) df2.style.format({'link': make_clickable_both})
问题排查与改进方案
核心原因分析
- 搜索页选择器精度不足:
.srp-results li.s-item会匹配到页面中的广告条、推荐条目等非目标商品,导致实际有效商品数远低于60条/页。 - 商品页面解析无异常处理:部分商品页面DOM结构与预期不符,
select_one返回None时直接调用.text会抛出异常,异常未被捕获会导致该条目无法加入数据列表,且中断当前循环的后续处理。 - 请求特征易被识别:仅依赖sleep未模拟浏览器请求头,eBay可能已对请求做限流,返回的搜索页内容缺失部分商品条目。
具体改进措施
- 优化搜索页选择器:使用更精准的选择器过滤无效条目,比如:
items = soup.select('#srp-results ul.srp-results li.s-item:not(.s-item--advertisement)') - 添加解析异常捕获与判空:对每个DOM元素的提取做判空处理,避免异常中断:
# 示例:商品名称提取 name_elem = content.select_one('h1.x-item-title__mainTitle > span') item_name = name_elem.text.strip() if name_elem else '未知名称' # 其他字段如condition、price同理处理 - 完善请求头模拟浏览器:添加User-Agent等字段降低爬虫识别概率:
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', 'Accept-Language': 'en-US,en;q=0.9' } # 请求搜索页和商品页时传入headers soup = BeautifulSoup(requests.get(page_url, headers=headers).text, 'html.parser') - 添加每页条目数校验:在循环中打印当前页抓取到的有效商品数,确认是否符合预期:
print(f"第{page}页有效商品数:{len(items)}") - 商品去重:从商品URL中提取唯一ID,用集合记录已抓取的ID,避免重复抓取:
crawled_ids = set() # 提取商品ID item_id = re.search(r'/itm/(\d+)/', item_url).group(1) if re.search(r'/itm/(\d+)/', item_url) else None if item_id not in crawled_ids: crawled_ids.add(item_id) # 执行商品页解析逻辑
内容的提问来源于stack exchange,提问作者Flintzer0
相关产品推荐
相关产品推荐

