多平台电商数据获取适配:淘宝 / 京东 / 拼多多差异化抓取技巧全解析
一、三大平台核心差异化总览(先辨差异,再定方案)
平台 | 页面渲染特征 | 核心反爬机制 | 接口特征 | 推荐工具组合 |
|---|---|---|---|---|
淘宝 | 全动态JS渲染,页面源码无真实商品数据;商品详情页需登录验证 | 滑块验证码、UA校验、Cookie验证、接口参数加密、IP封禁严格 | 接口参数加密(sign、token),JSON格式返回,需解密后解析 | Selenium + ddddocr + 代理IP |
京东 | 混合渲染(列表页静态+详情页动态),部分页面支持直接解析源码 | IP封禁、请求头校验、访问频率限制,无复杂验证码(普通场景) | 接口规范,参数透明(页码、分类ID),JSON格式返回,无需加密 | requests + 代理池(优先接口) |
拼多多 | 全动态JS渲染,滚动加载更多商品,页面元素类名动态生成 | IP封禁、请求频率限制、接口签名验证,无需登录即可获取基础数据 | 接口需携带签名参数(msToken、x-signture),参数易变动 | Selenium + 动态滚动 + 代理IP |
二、分平台差异化抓取技巧全解析(实战落地重点)
2.1 淘宝:加密接口+验证码,适配核心是“伪装与解密”
2.1.1 核心适配技巧
Cookie适配:淘宝商品详情页、部分列表页需登录后才能获取数据,需从浏览器复制登录后的Cookie(F12→应用→Cookie),添加到请求头,定期更新(Cookie有效期约1-7天)。
验证码应对:触发滑块验证码时,用ddddocr库识别滑块缺口,结合Selenium模拟滑块拖动(避免手动操作,实现自动化)。
接口解密:淘宝商品数据接口(如搜索接口)的参数(如sign、tmsign)会加密,新手可暂避接口,用Selenium模拟浏览器渲染后解析页面(降低难度);进阶可分析JS加密逻辑,解密参数后请求接口。
请求伪装:随机切换UA(fake-useragent),添加Referer(模拟从淘宝首页跳转),控制请求频率(每请求1页休息5-8秒),避免机械性请求。
2.1.2 实战代码(Selenium+验证码识别,抓取淘宝商品列表)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
import time
import ddddocr
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
# 初始化参数(替换为自己的淘宝Cookie)
taobao_cookie = "你的淘宝登录Cookie"
target_url = "https://s.taobao.com/search?q=手机" # 淘宝搜索页面(手机品类)
ua = UserAgent()
parsed_data = []
# 初始化浏览器(伪装配置,避免被识别)
def init_taobao_browser():
options = webdriver.ChromeOptions()
options.add_argument("--headless=new") # 无头模式(服务器运行可启用)
options.add_argument("--disable-gpu")
options.add_argument(f"user-agent={ua.random}")
# 禁用浏览器特征识别,伪装真实浏览器
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
# 添加Cookie(避免登录)
driver.get("https://www.taobao.com/")
time.sleep(2)
for cookie in taobao_cookie.split(";"):
key, value = cookie.split("=", 1)
driver.add_cookie({"name": key.strip(), "value": value.strip()})
return driver
# 滑块验证码识别与拖动(核心适配淘宝反爬)
def handle_slide_captcha(driver):
try:
# 定位滑块元素(根据淘宝验证码页面调整XPath)
slide = driver.find_element(By.XPATH, '//div[@class="slider-btn"]')
# 定位验证码图片
captcha_img = driver.find_element(By.XPATH, '//div[@class="captcha-img"]').screenshot_as_png
# 用ddddocr识别缺口位置
ocr = ddddocr.DdddOcr()
res = ocr.slide_match("blank.png", captcha_img, simple_target=True)
# 模拟拖动滑块
ActionChains(driver).click_and_hold(slide).move_by_offset(res["target"][0], 0).release().perform()
time.sleep(3)
print("验证码处理成功")
except Exception as e:
print("未触发验证码或处理失败:", str(e))
# 抓取淘宝商品列表数据
def crawl_taobao(driver):
driver.get(target_url)
time.sleep(3)
# 处理可能出现的滑块验证码
handle_slide_captcha(driver)
# 模拟滚动页面(淘宝动态加载商品,需滚动才能获取完整数据)
for i in range(3):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(4)
# 解析页面数据
html = driver.page_source
soup = BeautifulSoup(html, "lxml")
# 淘宝商品项定位(类名动态生成,用稳定的属性定位)
goods_items = soup.find_all("div", class_="item J_MouserOnverReq")
for item in goods_items:
try:
# 商品标题(淘宝标题包含换行,需处理)
title = item.find("a", class_="J_ClickStat").text.strip().replace("\n", "")
# 商品价格(淘宝价格有折扣价,区分现价与原价)
current_price = item.find("strong", class_="J_price").text.strip()
original_price = item.find("div", class_="original-price").text.strip() if item.find("div", class_="original-price") else current_price
# 销量(淘宝销量格式为"xxx+",需处理)
sales = item.find("div", class_="deal-cnt").text.strip().replace("+", "").replace("笔", "")
# 店铺名称
shop_name = item.find("a", class_="shopname").text.strip()
# 商品链接
goods_url = item.find("a", class_="J_ClickStat")["href"]
if not goods_url.startswith("http"):
goods_url = "https:" + goods_url
# 存储数据
parsed_data.append({
"平台": "淘宝",
"商品标题": title,
"现价(元)": current_price,
"原价(元)": original_price,
"销量": sales,
"店铺名称": shop_name,
"商品链接": goods_url
})
except Exception as e:
print("单条商品解析失败:", str(e))
print(f"淘宝抓取完成,共获取商品{len(parsed_data)}条")
# 主函数运行
if __name__ == "__main__":
driver = init_taobao_browser()
try:
crawl_taobao(driver)
finally:
driver.quit()
print("浏览器已关闭")2.1.3 淘宝专属避坑点
Cookie更新:若出现“请登录”提示,说明Cookie失效,需重新从浏览器复制登录后的Cookie。
验证码频率:同一IP触发验证码3次以上会被封禁,需搭配高匿代理IP,每抓取2-3页切换一次IP。
定位规则:淘宝商品项的类名会动态变化,优先用“item J_MouserOnverReq”等稳定的类名,或用data-id属性定位。
2.2 京东:接口规范+混合渲染,适配核心是“优先接口+控制频率”
2.2.1 核心适配技巧
接口优先:京东商品列表、详情页均有对应的JSON接口(F12→网络→XHR筛选),接口参数(页码page、分类ID、搜索关键词)透明,请求接口效率是页面解析的10倍以上。
分页适配:京东分页参数为“page=xx”(列表页),部分页面为“s=xx”,需根据目标页面的URL规则调整分页拼接逻辑(如京东搜索页分页URL:https://search.jd.com/Search?keyword=手机&page=1)。
请求控制:京东对IP访问频率限制较松,但单次抓取页数过多(超过20页)仍会被封禁,需控制请求频率(每请求1页休息3-5秒),搭配简单代理池即可。
数据解析:接口返回JSON格式数据,直接通过键名提取,无需解析HTML;部分详情页需用Selenium渲染,应对动态加载的规格参数。
2.2.2 实战代码(requests+接口,抓取京东商品列表,效率最优)
import requests
import json
from fake_useragent import UserAgent
import pandas as pd
import time
from proxy_pool import Pool # 简单代理池(需提前安装配置)
# 初始化参数
target_keyword = "手机" # 搜索关键词
page_count = 5 # 抓取前5页
parsed_data = []
ua = UserAgent()
# 初始化代理池(应对京东IP封禁)
proxy_pool = Pool()
# 京东接口请求(核心:接口参数透明,无需加密)
def crawl_jd_api():
for page in range(1, page_count + 1):
try:
# 京东搜索接口(从浏览器网络面板复制,替换关键词和页码)
api_url = f"https://search.jd.com/api/search?keyword={target_keyword}&page={page}&JL=6_0_0&abtest=3&wq=手机"
# 伪装请求头
headers = {
"User-Agent": ua.random,
"Accept": "application/json, text/plain, */*",
"Referer": f"https://search.jd.com/Search?keyword={target_keyword}&page={page}",
"Host": "search.jd.com"
}
# 获取代理IP(可选,抓取页数少时可省略)
proxy = proxy_pool.get_proxy()
proxies = {"http": proxy, "https": proxy} if proxy else None
# 发送请求(设置超时,避免无限等待)
response = requests.get(api_url, headers=headers, proxies=proxies, timeout=10)
response.raise_for_status()
# 解析JSON数据(京东接口返回有多余字符,需处理)
data_str = response.text.lstrip("fetchJSON_comment98(").rstrip(");")
data = json.loads(data_str)
# 提取商品列表数据
goods_list = data.get("29", {}).get("skuList", [])
for goods in goods_list:
parsed_goods = {
"平台": "京东",
"商品ID": goods.get("skuId", ""),
"商品标题": goods.get("name", "未知").replace("<em>", "").replace("</em>", ""), # 去除高亮标签
"现价(元)": goods.get("jdPrice", {}).get("p", 0),
"原价(元)": goods.get("jdPrice", {}).get("op", 0),
"销量": goods.get("commentCount", 0), # 京东用评论数替代销量(近似值)
"店铺名称": goods.get("shopName", "未知"),
"商品链接": f"https://item.jd.com/{goods.get('skuId', '')}.html"
}
parsed_data.append(parsed_goods)
print(f"京东第{page}页抓取完成,获取商品{len(goods_list)}条")
# 控制请求频率
time.sleep(4)
except Exception as e:
print(f"京东第{page}页抓取失败:", str(e))
time.sleep(10) # 失败后延长休息时间,避免连续失败
# 保存数据到Excel
def save_data():
df = pd.DataFrame(parsed_data)
df.to_excel("京东商品数据.xlsx", index=False, encoding="utf-8-sig")
print("数据保存成功!")
# 主函数运行
if __name__ == "__main__":
crawl_jd_api()
save_data()2.2.3 京东专属避坑点
接口格式:京东接口返回的JSON字符串前后有多余字符(如fetchJSON_comment98(...)),需用lstrip、rstrip处理后再解析。
销量字段:京东接口不直接返回销量,可用commentCount(评论数)近似替代,精准销量需解析商品详情页。
代理使用:抓取页数≤10页时,可不用代理;超过10页需搭配代理池,避免IP被临时封禁。
2.3 拼多多:动态渲染+签名验证,适配核心是“模拟滚动+签名适配”
2.3.1 核心适配技巧
动态滚动适配:拼多多商品列表需滚动页面才能加载更多数据,需用Selenium模拟滚动,滚动次数根据目标页数调整(一般每滚动1次加载20条商品)。
元素定位:拼多多商品项的类名是动态生成的(如“goods-item_123”),无法固定定位,需用“div[contains(@class, 'goods-item')]”模糊定位,或根据父元素定位。
签名验证:拼多多接口需携带msToken、x-signture等签名参数,签名规则会定期变动,新手可暂避接口,用Selenium解析渲染后的页面(降低适配难度);进阶可分析JS签名逻辑,动态生成签名参数。
请求频率:拼多多对IP封禁较严格,每滚动1次休息3-4秒,搭配高匿代理IP,避免集中请求。
2.3.2 实战代码(Selenium+动态滚动,抓取拼多多商品列表)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
import pandas as pd
# 初始化参数
target_url = "https://mobile.yangkeduo.com/search_result.html?keyword=手机" # 拼多多搜索页(移动端适配,更易抓取)
scroll_count = 3 # 滚动次数(每滚动1次加载20条商品)
parsed_data = []
ua = UserAgent()
# 初始化浏览器(拼多多对移动端UA更友好,可伪装移动端)
def init_pdd_browser():
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--disable-gpu")
# 伪装移动端UA(降低被识别概率)
options.add_argument("user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1")
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
return driver
# 模拟滚动页面(拼多多核心适配:滚动加载商品)
def scroll_page(driver):
for i in range(scroll_count):
# 滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
print(f"第{i+1}次滚动,等待商品加载...")
time.sleep(4) # 等待JS加载商品,避免加载不完整
# 抓取拼多多商品数据
def crawl_pdd(driver):
driver.get(target_url)
time.sleep(3)
# 模拟滚动,加载完整商品数据
scroll_page(driver)
# 解析页面数据
html = driver.page_source
soup = BeautifulSoup(html, "lxml")
# 拼多多商品项模糊定位(类名动态生成,用contains匹配)
goods_items = soup.find_all("div", class_=lambda x: x and "goods-item" in x)
for item in goods_items:
try:
# 商品标题(拼多多标题较长,需截取)
title = item.find("div", class_=lambda x: x and "goods-name" in x).text.strip()[:50] # 截取前50字,避免过长
# 商品价格
current_price = item.find("div", class_=lambda x: x and "goods-price" in x).text.strip().replace("¥", "")
# 销量(拼多多销量格式为"已售xxx")
sales = item.find("div", class_=lambda x: x and "sales-volume" in x).text.strip().replace("已售", "").replace("+", "")
# 店铺名称
shop_name = item.find("div", class_=lambda x: x and "shop-name" in x).text.strip()
# 商品链接
goods_url = item.find("a")["href"]
if not goods_url.startswith("http"):
goods_url = "https:" + goods_url
# 存储数据
parsed_data.append({
"平台": "拼多多",
"商品标题": title,
"现价(元)": current_price,
"销量": sales,
"店铺名称": shop_name,
"商品链接": goods_url
})
except Exception as e:
print("单条商品解析失败:", str(e))
print(f"拼多多抓取完成,共获取商品{len(parsed_data)}条")
# 保存数据
def save_data():
df = pd.DataFrame(parsed_data)
df.to_excel("拼多多商品数据.xlsx", index=False, encoding="utf-8-sig")
print("数据保存成功!")
# 主函数运行
if __name__ == "__main__":
driver = init_pdd_browser()
try:
crawl_pdd(driver)
save_data()
finally:
driver.quit()
print("浏览器已关闭")2.3.3 拼多多专属避坑点
移动端适配:拼多多PC端反爬更严格,优先使用移动端URL(mobile.yangkeduo.com),伪装移动端UA,抓取更稳定。
类名定位:商品项、价格、标题的类名均会动态生成,必须用模糊定位(lambda x: x and "xxx" in x),避免定位失败。
滚动次数:滚动次数过多(超过5次)易触发IP封禁,需控制滚动次数,搭配代理IP切换。
三、多平台通用适配技巧(一次适配,多平台复用)
3.1 工具复用:一套代码框架,多平台适配
import time
import pandas as pd
from fake_useragent import UserAgent
# 通用初始化:生成随机UA
def init_common():
ua = UserAgent()
return ua
# 通用代理IP获取(多平台复用)
def get_proxy():
from proxy_pool import Pool
proxy_pool = Pool()
return proxy_pool.get_proxy()
# 通用数据保存(多平台复用,保存为Excel/CSV)
def save_common_data(data, platform_name):
df = pd.DataFrame(data)
df.to_excel(f"{platform_name}商品数据.xlsx", index=False, encoding="utf-8-sig")
df.to_csv(f"{platform_name}商品数据.csv", index=False, encoding="utf-8-sig")
print(f"{platform_name}数据保存成功!")
# 通用请求频率控制(多平台复用)
def control_frequency(seconds=4):
time.sleep(seconds)
# 多平台抓取入口(复用框架,修改专属逻辑)
def crawl_platform(platform="taobao"):
ua = init_common()
proxy = get_proxy()
parsed_data = []
if platform == "taobao":
# 淘宝专属抓取逻辑(请求、解析、反爬)
pass
elif platform == "jd":
# 京东专属抓取逻辑(请求、解析、反爬)
pass
elif platform == "pdd":
# 拼多多专属抓取逻辑(请求、解析、反爬)
pass
# 通用保存数据
save_common_data(parsed_data, platform)
# 调用多平台抓取
if __name__ == "__main__":
crawl_platform("taobao")
crawl_platform("jd")
crawl_platform("pdd")3.2 反爬通用应对:代理IP+请求伪装+异常捕获
代理IP适配:三大平台均需使用高匿代理IP,避免使用透明代理(易被识别);推荐搭建简单代理池(proxy_pool+Redis),实现IP自动切换、失效剔除。
请求伪装:统一使用fake-useragent生成随机UA,添加Referer(模拟从平台首页跳转),避免固定请求头;淘宝需额外添加Cookie,京东、拼多多可省略。
异常捕获:所有平台的抓取代码均需添加try-except捕获异常(请求超时、元素不存在、IP失效等),避免程序崩溃;失败后延长休息时间,重试1-2次。
3.3 数据解析通用技巧:空值处理+格式统一
空值处理:解析每个字段时,用if判断元素/键是否存在,避免空值导致程序崩溃(如title = item.find("xxx")?.text.strip() or "未知")。
格式统一:统一价格(保留2位小数)、销量(转换为数字格式)、商品标题(去除多余空格、换行、高亮标签)。
去重处理:多平台抓取可能出现重复商品(同一商品在多个平台上架),可根据商品ID、商品标题去重,保留唯一数据。
四、多平台抓取避坑汇总(高频问题+解决方案)
高频问题 | 涉及平台 | 解决方案 |
|---|---|---|
IP被封禁,无法访问平台 | 淘宝、拼多多(高频),京东(低频) | 1. 停止请求,更换高匿代理IP;2. 降低请求频率(每页休息5-8秒);3. 伪装移动端UA,减少被识别概率;4. 淘宝需重新更新Cookie。 |
数据解析为空,定位失败 | 拼多多(高频),淘宝(中频) | 1. 拼多多:改用模糊定位(contains匹配类名),检查滚动是否加载完整;2. 淘宝:更新Cookie,检查元素类名是否动态变化;3. 打印页面源码,确认数据是否存在。 |
接口请求失败,返回403/404 | 淘宝(高频),京东、拼多多(低频) | 1. 淘宝:检查接口参数是否加密,新手改用Selenium页面解析;2. 京东/拼多多:检查请求头是否完整,更换代理IP,控制请求频率。 |
验证码无法自动处理 | 淘宝(唯一) | 1. 升级ddddocr库,重新训练滑块识别模型;2. 避免同一IP连续触发验证码,提前切换代理;3. 手动处理1次验证码后,保存Cookie复用。 |
商品数据加载不完整 | 拼多多(高频),淘宝(中频) | 1. 增加滚动次数和等待时间(滚动后休息4-5秒);2. 淘宝:处理完验证码后再滚动;3. 拼多多:伪装移动端UA,避免加载异常。 |
程序崩溃,无法持续抓取 | 三大平台通用 | 1. 给所有请求、解析逻辑添加try-except异常捕获;2. 设置请求超时时间(10秒以内);3. 实现断点续爬,保存已抓取数据,避免重复抓取。 |
五、合规提示与延伸方向
5.1 合规抓取提示(必看)
遵守robots协议:查看各平台robots.txt文件(如淘宝:https://www.taobao.com/robots.txt),不抓取协议禁止的内容(如用户隐私、敏感数据)。
控制抓取频率:避免过度抓取,给平台服务器造成压力,建议单平台单日抓取页数不超过50页。
数据用途合规:抓取的数据仅用于个人学习、市场分析,不得用于商业侵权、恶意竞争、刷单等非法用途;不得泄露抓取的店铺信息、用户数据。
5.2 延伸方向(进阶提升)
接口加密解密:深入分析淘宝、拼多多的接口签名逻辑(如淘宝的sign参数、拼多多的msToken),实现接口参数动态生成,替代Selenium,提升抓取效率。
分布式抓取:使用Scrapy框架+Redis,实现多线程、多节点分布式抓取,应对大规模多平台数据获取需求。
验证码自动识别:学习深度学习相关技术,优化滑块验证码、图形验证码的识别精度,实现全自动化抓取。
数据可视化:将多平台抓取的数据,结合matplotlib、pyecharts等库,实现销量趋势分析、价格对比、品类分布可视化,让数据产生价值。
