一、案例背景:
最近一个客户在做关于淘宝详情页sku类目及券前后价格采集的自动化流程,询问我们这边有没有比较好的方法,目前客户采用的方式的正常的打开网页,然后进行遍历点击【颜色分类】里面的每个SKU,然后再去采集券前和券后的价格,相对来说速度会比较慢些。
二、场景解决方法:
该场景目前有三种方案,以下会对三种方案的优点与缺点进行分析对比
本次文档编写介绍使用网页监听去进行数据采集
①:可视化操作:
方法:捕获sku相似元素组,然后循环点击,采集每一个sku的券前和券后价格
优势:易理解、思路清晰
劣势:方法相对不是高B格,流程速度效率相对较慢
②:网络抓包、爬虫:
方法:直接通过网络请求,分析对应请求包数据,然后通过rquests发送网络请求,解析请求结果
优势:速度快,省去可视化操作
劣势:需要对http请求比较熟悉,熟悉天猫sign签名算法
③:网页监听:
方法:使用影刀现成的网页监听指令,通过刷新网页后,找到目标请求数据包进行解析
优势:无需考虑天猫sign签名算法,可对请求地址进行url通配,速度相对较快
劣势:需要对http请求比较熟悉,熟悉监听指令使用方法
三、前置准备:
①:目标url网址拼接:
目标网址的url地址其实是可以进行简化的
简化成:'https://detail.tmall.com/item.htm?&' + 'id=xxxxx'
②:商品id获取:
商品ID存在于搜索关键词以后,每个商品元素里面的<a>标签内
通过正则表达式可以提取id内容
正则表达式:(?<=id=).*(?=&spm)
链接地址:https://detail.tmall.com/item.htm?id=691252362559&spm=a21n57.1.item.1.7746523cYH9kJh&priceTId=2147828717230835206811316ee440&utparam=%7B%22aplus_abtest%22:%222f3f6034bb86ebd9bface1e465447c8f%22%7D&xxc=ad_ztc&pisk=fWTStH0L9825RydfKghVcaeMyaQBALgaFW1psBUz9aQRpnOMdTlnqa-fdKpfezloqMBBEaIH49WPdwOHCjkZ7VRkZwjKQAuNLgZanNqRwgeFDsCCqxl43VRkZ9V7pf-x7k1O_k8d9pIRDiCCH_BdvzhfD1fNJzILyoeAn6QdppB-kqC1N8Ude6exBIHfi06JNjeceX1UHAECHyUpy2jPCv6AisTjdgB6wEUTWXf5VOdRhAz74SIvtMT3tysewhvh6Le-d9YXMUK9BxrPeh1B_H9tTufVAUbfpU3g1tLWOEsk08ER1a65XUI7_fAlvnTfzUH3jIRfeG_20mDPYa9WjOj-mxvBGTJpPieS39-wgUIXBxzXKMtpzZL-HVsyiPW68NqQGG4CGOljGkqeDpiTEMQHtxSRis8ZGjw7xgCcGOljGkqh2sfVbjGbFkf..&sku_properties=13297542:29440;122216769:14863995
③:网络抓包:
目标请求地址:
https://h5api.m.tmall.com/h5/mtop.taobao.pcdetail.data.get/1.0/?jsv=2.6.1&appKey=12574478&t=1723086901697&sign=690e2f4c9547be36b6286fc7fc1b4a67&api=mtop.taobao.pcdetail.data.get&v=1.0&isSec=0&ecode=0&timeout=10000&ttid=2022%40taobao_litepc_9.17.0&AntiFlood=true&AntiCreep=true&preventFallback=true&type=jsonp&dataType=jsonp&callback=mtopjsonp1&data=%7B%22id%22%3A%22691252362559%22%2C%22detail_v%22%3A%223.3.2%22%2C%22exParams%22%3A%22%7B%5C%22id%5C%22%3A%5C%22691252362559%5C%22%2C%5C%22sku_properties%5C%22%3A%5C%2213297542%3A29440%3B122216769%3A14863995%5C%22%2C%5C%22queryParams%5C%22%3A%5C%22id%3D691252362559%26sku_properties%3D13297542%253A29440%253B122216769%253A14863995%5C%22%2C%5C%22domain%5C%22%3A%5C%22https%3A%2F%2Fdetail.tmall.com%5C%22%2C%5C%22path_name%5C%22%3A%5C%22%2Fitem.htm%5C%22%7D%22%7D
网页监听的时候不需要这么多,使用*通配符的方法,将那些变化的t以及签名参数sign通通替换*号,替换如下:
https://h5api.m.tmall.com/h5/mtop.taobao.pcdetail.data.get/1.0/?jsv=2.6.1&appKey=12574478&t=*&sign=*&api=mtop.taobao.pcdetail.data.get*&data=*
四、实现过程:
应用版本:【编码版】的应用
核心思路:开始网页监听--->刷新网页--->监听指定资源路径--->分析监听结果--->解析满足条件的监听结果
①:完整代码:
输出结果格式:['sku名称','skuid','券前价','券后价']
有些sku是没有券后价格的,所以如果没有券后价格,那么会写'无券后价格'
# 使用提醒:
# 1. xbot包提供软件自动化、数据表格、Excel、日志、AI等功能
# 2. package包提供访问当前应用数据的功能,如获取元素、访问全局变量、获取资源文件等功能
# 3. 当此模块作为流程独立运行时执行main函数
# 4. 可视化流程中可以通过"调用模块"的指令使用此模块
import xbot
from xbot import print, sleep,web
from .import package
from .package import variables as glv
import re
import json
import time
import random
def main(args):
pass
class get_price_data():
def __init__(self,id_list):
self.id_list = id_list
def get_data(self,sku_id):
# 打开目标网页
web_page = xbot.web.create(url = f'https://detail.tmall.com/item.htm?&id={sku_id}',mode = 'chrome',load_timeout = 20)
web_page.wait_load_completed(timeout = 20)
# 开始网页监听
web_page.start_monitor_network()
web_page.reload() # 网页刷新
network_result_list = web_page.get_responses(url='https://h5api.m.tmall.com/h5/mtop.taobao.pcdetail.data.get/1.0/?jsv=2.6.1&appKey=12574478&t=*&sign=*&api=mtop.taobao.pcdetail.data.get*&data=*', use_wildcard=True, resource_type='All')
web_page.stop_monitor_network()
web_page.close() # 关闭网页
for network_data in network_result_list:
if network_data['url'].startswith('https://h5api.m.tmall.com/h5/mtop.taobao.pcdetail.data.get/1.0/'):
regex = ' mtopjsonp1\((.*)\)'
pattern = re.compile(regex,re.S)
res_data = pattern.findall(network_data['body'])[0] # 提取正则表达式结果
json_data = json.loads(res_data) # 转换为json对象
# sku标题采集
name_list = [x['name'] for x in json_data['data']['skuBase']['props'][0]['values']]
# sku id采集
sku_list = [x['skuId'] for x in json_data['data']['skuBase']['skus']]
# sku 券前、券后价格
price_list = []
for ind, v in enumerate(sku_list):
data_1 = json_data['data']['skuCore']['sku2info'].get(v, None)
price_Before = data_1.get('price', None)
price_After = data_1.get('subPrice', None)
name = name_list[ind]
sku_id = sku_list[ind]
if price_Before != None and price_After != None:
price_Before = price_Before.get('priceText', '无价格')
price_After = price_After.get('priceText', '无券后价格')
price_list.append([name, sku_id, price_Before, price_After])
elif price_Before != None and price_After == None:
price_Before = price_Before.get('priceText', '无价格')
price_After = '无券后价格'
price_list.append([name, sku_id, price_Before, price_After])
return price_list
def run(self):
total_data_list = []
for id in self.id_list:
price_list = self.get_data(id)
total_data_list.extend(price_list)
time.sleep(random.randint(5, 7)) # 睡眠5-7秒 继续下一个
return total_data_list
id_list = ['805182750525','623249086278']
spider = get_price_data(id_list)
print(spider.run())
# 输出:
[
['1筒装-金属回形针', '5648271815373', '11', '9.9'],
['1筒装-彩色回形针', '5648271815374', '10.6', '9.5'],
['1筒装-炫黑回形针', '5648271815375', '11.2', '10'],
['1筒装-莫兰迪回形针', '5648271815376', '10.6', '9.5'],
['2筒装-金属回形针', '5648271815377', '17.6', '15.8'],
['2筒装-彩色回形针', '5648271815378', '15.6', '14'],
['2筒装-炫黑回形针', '5648271815379', '17.8', '16'],
['2筒装-莫兰迪回形针', '5648271815380', '15.6', '14'],
['3筒装-金属回形针', '5648271815381', '25.6', '23'],
['3筒装-彩色回形针', '5648271815382', '23.6', '21.2'],
['3筒装-炫黑回形针', '5648271815383', '25.8', '23.2'],
['3筒装-莫兰迪回形针', '5648271815384', '23.6', '21.2'],
['1彩色回形针+2金属回形针', '5648271815385', '23.6', '21.2'],
['1炫黑回形针+2金属回形针', '5648271815386', '25.8', '23.2'],
['彩色工字钉3筒装', '5648271815387', '36', '32.4'],
['3筒装-金属大头针', '5648271815388', '27.6', '24.8'],
['1工字钉+2金属回形针', '5648271815389', '25.6', '23'],
['1大头针+2金属回形针', '5648271815390', '25.6', '23'],
['1金属回形针+1彩色回形针+1工字钉', '5648271815391', '25.6', '23'],
['1彩色回形针+1金属回形针+1大头针', '5648271815392', '25.6', '23'],
['1金属回形针+1工字钉+1大头针', '5648271815393', '25.6', '23'],
['1彩色回形针+1工字钉+1大头针', '5648271815394', '25.6', '23'],
['三针一钉4件套', '5648271815395', '31.4', '28.2'],
['1盒装-彩色回形针', '5648271815396', '9.4', '8.46'],
['红色', '4579371411412', '133', '无券后价格'],
['深蓝色', '4579371411413', '133', '无券后价格']
]
②:影刀使用截图:
插入python代码段:
from ._jianting import get_price_data
from xbot import print
spider = get_price_data(id_list)
total_list = spider.run()
print(total_list)