原创来自本人的公众号:阿嚏个技术
公众号文章地址: 得物、京东、唯品会比价数据的实现
无论是自己买鞋,还是在不同平台折腾炒鞋或其他潮品,进行不同平台的比价是比较重要的方式。本文介绍得物、京东和唯品会三个平台,需要爬哪些接口实现价格的对比。
1、唯品会
通过对其h5网址的分析,主要爬取接口的地址是:https://mapi.vip.com/vips-mobile/rest/shopping/wap2/vendorSkuList/v4,在浏览器开发者工具里跟踪下就可以获取请求的参数,拼装到python代码里就可以实现。
def get_prd_detail(brandid, mid):
url = 'https://mapi.vip.com/vips-mobile/rest/shopping/wap2/vendorSkuList/v4'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
'Referer': 'https://detail.vip.com/',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'authorization': 'OAuth api_sign=3b940d8aef703d7a836de55acadae2ceed21a37f',
}
params = {
'app_name': 'shop_wap',
'app_version': '4.0',
'api_key': '8cec5243ade04ed3a02c5972bcda0d3f',
'mobile_platform': '2',
'source_app': 'yd_wap',
'warehouse': 'VIP_NH',
'fdc_area_id': '104105101',
'province_id': '104105',
'mars_cid': '1617287470390_5842d9f97ec075198a5051e92611800d',
'mobile_channel': 'mobiles-||',
'standby_id': 'nature',
'mid': '{}'.format(mid),
'brandid': '{}'.format(brandid),
'device': '3',
'salePriceVer': '2',
'functions': 'svipAsSalePrice,fallingInfo,announcement,midSupportServices,userContext,buyLimit,foreShowActive,panelView,futurePriceView,showSingleColor,noProps,sku_price,active_price,prepay_sku_price,reduced_point_desc,surprisePrice,businessCode,promotionTips,invisible,flash_sale_stock,restrictTips,favStatus,banInfo,futurePrice,priceChart,priceView,quotaInfo,exclusivePrice,extraDetailImages,floatingView',
'prepayMsgType': '1',
'promotionTipsVer': '5',
'priceViewVer': '8',
'supportSquare': '1',
'panelViewVer': '2',
'isUseMultiColor': '1',
'couponInfoVer': '2',
'freightTipsVer': '3',
'serviceTagVer': '1',
'supportAllPreheatTipsTypes': '1',
'salePriceTypeVer': '2',
'wap_consumer': 'B',
'_': '1620389036',
}
return requests.get(url, headers=headers, params=params)
其中headers中的authorization是需要进行加密计算的,主要是对api, hash_param, sid, cid, secret这几个数据,sid和cid是cookie里值,secret是个固定值,跟params中的api-key有关,然后对这些数据做sha1处理,具体算法请见公众号对应的文章。
在接口返回的json内容里,在data.product_price_range_mapping.priceView.finalPrice下的price是券后价,用户真正购买时支付的价格。在priceView.salePrice下的saleMarketPrice和salePrice分别是“市场价”和“销售价”,均是在页面上显示的价格,这都是电商平台惯用的伎俩,通过不同价格的显示,暗示用户占到低价的便宜了。
2、京东
京东对反爬相对比较宽松,因此采用了selenium.webdriver来实现爬虫,这种方式就是纯粹模仿浏览器的加载方式,然后通过分析网页dom结构来找到价格的位置。这种方式相对比较简单,但是因为整个页面下载,数据量比接口方式的大,分析效率也低,并且还需要模拟浏览页面时的下滑动作,否则有些内容就不会被加载。
def get_goods_by_urls(self):
db = DbClass()
try:
for url in self.urls:
self.browser.get(url)
html_add_js = self.browser.page_source
# 使用BS4进行分析:
data_soup = BeautifulSoup(html_add_js, 'lxml')
# 获取商品简略信息
div_result = data_soup.select('.jGoodsList .jSubObject')
params = {}
for i in range(0, len(div_result)):
# 相关数据爬取
try:
print(div_result[i])
params['url'] = div_result[i].select('.jPic a')[0].attrs['href']
if 'https' not in params['url']:
params['url'] = 'https:' + params['url']
params['title'] = div_result[i].select('.jDesc a')[0].string
# tmp = div_result[i].select('.jdPrice span')
# goods[i]['price'] = div_result[i].select('.jdPrice .jdNum')[0].string
# 进入详情页
print('Get detail info',params['title'])
self.browser.get(params['url'])
html_add_js = self.browser.page_source
# 使用BS4进行分析:
data_soup = BeautifulSoup(html_add_js, 'lxml')
div_detail = data_soup.select('.J-summary-price .price')
params['price'] = div_detail[0].string
# 获取商品尺寸信息
div_detail = data_soup.select('#choose-attr-2 .item')
params['sizes'] = [size.attrs['data-value'] for size in div_detail]
# 获取商品货号信息
div_detail = data_soup.select('.parameter2 li')
for param in div_detail:
if '货号' in param.string:
params['prdno'] = param.attrs['title']
print('Get all params:',params)
self.save_goods(db, params)
print('save into db finished')
params.clear()
except Exception as e:
print('Parse itemlists error:', e)
except Exception as e:
print(e)
db.close()
上面的代码的主要功能就是找数据所用的class或id所在div的路径,然后通过取属性或值,来获得需要的数据。
3、得物
得物爬虫的接口地址主要是在架销售的各种价格,https://app.dewu.com/api/v1/h5/inventory/price/h5/queryBuyNowInfo,看过我文章和视频的朋友会知道,主要是模拟小程序方式实现的爬虫。得物最近接口更新的很快,在反爬上甚至做得有些变态,个人觉得真没有必要,大家爬数据的目的,不就是想做决策工具,促进平台更高效的交易嘛。
得物爬虫实现主要是2个地方,一个是sign,一个是request和response的data的加解密,我在视频里已经讲得非常清楚在小程序的什么地方可以找到相关的处理,所以不要动不动就想找我“白piao”代码,本人的劳动希望得到尊重。
def buynow_load_data(spuId):
post_data = {
"spuId": spuId
}
sign = getsign(post_data)
post_data['sign'] = sign
hs['SK'] = gen_SK()
hs['sks'] = '1,hdw1'
hs['User-Agent'] = random.choice(user_agents)
res_data = request_post(query_buynow_url, headers=hs, data=json.dumps(post_data), is_proxy=is_proxy)
return res_data
在返回的json中,tradeChannelInfoList下可以看到不同尺码下有各种形式的价格,比如闪电价、普通价,不同价格是通过tradeType字段来区分,该参数不同的取值对应不同的价格形式:0=》普通价,1=》极速价,2=》闪电价,3=》跨境价,8=》品牌专攻,95=》全新微瑕等。
4、比价
拿到不同平台价格后,就可以进行对比价格,京东、唯品会的价格是不区分尺码的,而得物会区分,通过对比挖掘差价,就可以在得物上炒炒潮品了。简单做了个前端页面,如下:
比下来唯品会普遍比京东便宜,但京东叠加券的价格我还没有处理到,等再优化后看看会不会有所不同。得物上不同尺码价格会有明显的差异,上图尺码对应行里的数字有红有绿,表示在京东和唯品会买鞋然后拿去得物上卖,计算出或赚或赔的价格差,看上去还是有10%的赚头(这里是没有考虑得物平台服务相关费用的)。