如何用Python的Beautiful Soup实现拍卖网站新 listings 筛选
实现Trademe二手PRS电吉他新Listing监控
现有代码功能
你当前的代码可抓取Trademe上二手PRS电吉他的搜索结果,统计数量并输出标题:
from bs4 import BeautifulSoup import requests url = requests.get("https://www.trademe.co.nz/a/marketplace/music-instruments/instruments/guitar-bass/electric-guitars/search?search_string=prs&condition=used") soup = BeautifulSoup(url.text, "html.parser") listings = soup.findAll("div", attrs={"class":"tm-marketplace-search-card__title"}) print(len(listings)) for listing in listings: print(listing.text)
需求说明
希望仅展示每次抓取时新上线的listing,而非全部搜索结果。
优化实现方案
直接对比标题或数量容易出错(比如标题修改、重复标题、旧listing下架),更可靠的方式是抓取每个listing的唯一ID(Trademe的每个listing都有专属ID,可从标题的跳转链接中提取),通过对比已抓取的ID列表识别新内容。
具体实现代码
from bs4 import BeautifulSoup import requests # 存储已见过的listing ID的本地文件路径 SEEN_LISTINGS_FILE = "seen_prs_listings.txt" def load_seen_listings(): """读取本地存储的已抓取过的listing ID""" try: with open(SEEN_LISTINGS_FILE, "r") as f: return set(f.read().splitlines()) except FileNotFoundError: # 文件不存在则返回空集合 return set() def save_seen_listings(seen_ids): """将新的listing ID写入本地文件""" with open(SEEN_LISTINGS_FILE, "w") as f: f.write("\n".join(seen_ids)) def get_new_listings(): # 发起请求获取页面内容 url = "https://www.trademe.co.nz/a/marketplace/music-instruments/instruments/guitar-bass/electric-guitars/search?search_string=prs&condition=used" response = requests.get(url) soup = BeautifulSoup(response.text, "html.parser") # 抓取所有listing的标题和唯一ID(从链接中提取) listings = [] title_elements = soup.findAll("div", attrs={"class":"tm-marketplace-search-card__title"}) for title_elem in title_elements: # 获取跳转链接,格式类似 /a/marketplace/.../listing/1234567890 link = title_elem.find_parent("a")["href"] # 提取链接末尾的数字作为唯一ID listing_id = link.split("/")[-1] title = title_elem.text.strip() listings.append({"id": listing_id, "title": title}) # 加载已见过的ID,筛选新listing seen_ids = load_seen_listings() new_listings = [item for item in listings if item["id"] not in seen_ids] # 更新已见过的ID集合,包含当前所有listing的ID all_current_ids = {item["id"] for item in listings} save_seen_listings(seen_ids.union(all_current_ids)) return new_listings if __name__ == "__main__": new_listings = get_new_listings() if new_listings: print(f"发现{len(new_listings)}条新Listing:") for idx, listing in enumerate(new_listings, 1): print(f"{idx}. {listing['title']}") else: print("没有新的Listing")
代码说明
- 唯一ID提取:从标题的父级跳转链接中提取末尾数字作为ID,避免标题重复或修改导致的误判
- 本地存储:用文本文件保存已抓取过的ID,每次运行时先读取对比,再更新存储内容
- 增量更新:仅返回未见过的新listing,同时保留当前所有ID(避免旧listing重新上架时误判为新内容)
补充提示
- 可借助
schedule库添加定时任务,让脚本定期自动运行,实现持续监控 - 避免过于频繁请求Trademe服务器,防止触发反爬机制
内容的提问来源于stack exchange,提问作者Spykerwolf
相关产品推荐
相关产品推荐

