提交 5f8ad000 authored 作者: 梁业锦's avatar 梁业锦 💬

Merge branch 'master' of D:\diaoyun\zion with conflicts.

上级 0e0672de
{
"alternate": "\u8FDE\u5E3D\u77ED\u4E0A\u8863 - {alternatecolor} - 女 | H&M CN",
"articleCode":"0754698003", "baseProductCode" : "0754698_group_003", "categoryParentKey" : "/1/ladies",
"productKey": "0754698_group_003_zh_cn",
"collection": "",
"designerCollection": "",
"productType": "",
"ageGender": "",
"presentationTypes": "\u4E0A\u8863",
"materialDetails":[
{
"name":"\u68C9",
"description":"\u68C9\u662F\u6211\u4EEC\u6700\u5E38\u7528\u7684\u4E00\u79CD\u7EA4\u7EF4\uFF0C\u4F46\u68C9\u9700\u8981\u5927\u91CF\u7684\u6C34\u5206\u624D\u80FD\u751F\u957F\u3002\u6211\u4EEC\u7684\u76EE\u6807\u662F\u5728 2020 \u5E74\u524D\u4FDD\u8BC1\u6240\u7528\u7684\u6240\u6709\u68C9\u6599\u5747\u6765\u81EA\u4E8E\u73AF\u4FDD\u7684\u6E90\u5934\u3002\u00A0\u76EE\u524D\uFF0C\u6211\u4EEC\u4F7F\u7528\u4E09\u5927\u7C7B\u73AF\u4FDD\u68C9\uFF1A\u6709\u673A\u68C9\uFF08\u8FD9\u79CD\u68C9\u7684\u79CD\u690D\u8FC7\u7A0B\u4E0D\u4F7F\u7528\u4EFB\u4F55\u519C\u836F\u548C\u5316\u80A5\uFF0C\u4E14\u4E0D\u542B\u6709\u4EFB\u4F55\u8F6C\u57FA\u56E0\u6709\u673A\u4F53\uFF09\uFF1B\u56DE\u6536\u5229\u7528\u68C9\uFF08\u6765\u81EA\u4E8E\u65E7\u8863\u7269\u548C\u7EBA\u7EC7\u8FB9\u89D2\u6599\uFF09\uFF1B\u4EE5\u53CA\u6765\u81EA BCI\uFF08Better Cotton Initiative\uFF0C\u745E\u58EB\u826F\u597D\u68C9\u82B1\u53D1\u5C55\u534F\u4F1A\uFF09\u7684\u4F18\u8D28\u68C9\u82B1\uFF0C\u8FD9\u79CD\u68C9\u6709\u52A9\u4E8E\u51CF\u5C11\u5BF9\u5F53\u5730\u73AF\u5883\u7684\u538B\u529B\u5E76\u6539\u5584\u79CD\u690D\u793E\u533A\u7684\u798F\u7949\u3002"
}
,
{
"name":"\u805A\u916F\u7EA4\u7EF4",
"description":"\u5E38\u89C4\u7684\u805A\u916F\u7EA4\u7EF4\u662F\u7531\u5316\u77F3\u8D44\u6E90\uFF08\u539F\u6CB9\uFF09\u5236\u6210\u7684\u5E38\u7528\u4EBA\u9020\u7EA4\u7EF4\u3002\u6211\u4EEC\u4E00\u76F4\u52AA\u529B\u63D0\u9AD8\u53EF\u56DE\u6536\u805A\u916F\u7EA4\u7EF4\u7684\u4F7F\u7528\u7387\uFF1B\u8FD9\u662F\u4E00\u79CD\u4EE5 PET \u5851\u6599\u74F6\u7B49\u5E9F\u5F03\u7269\u5236\u6210\u7684\u66F4\u73AF\u4FDD\u7684\u6750\u6599\u3002\u6211\u4EEC\u8FD8\u79EF\u6781\u53C2\u4E0E\u7EBA\u7EC7\u54C1\u81F3\u7EBA\u7EC7\u54C1\u56DE\u6536\u5229\u7528\u6280\u672F\u7684\u7814\u53D1\uFF0C\u4EE5\u8FDB\u4E00\u6B65\u63D0\u5347\u518D\u751F\u805A\u916F\u7EA4\u7EF4\u7684\u73AF\u4FDD\u6027\uFF0C\u5E76\u8FBE\u5230\u8282\u7EA6\u81EA\u7136\u8D44\u6E90\u7684\u76EE\u7684\u3002"
}
],
"0754698001": {
"name": "\u6D45\u7C73\u8272\/Ariana Grande",
"inStore": false,
"energyClass": "",
"energyClassInterval": "",
"energyClassCode": "",
"energyClassIntervalCode": "",
"colorCode": "12",
"totalStyleWithArticles": "8",
"styleWithDefaultArticles":"0674606024,0733782002,0754357002,0490113015,0798110001,0766156006,0189626001,0766728004",
"productsWithStyleWith":"0754698_group_003_zh_cn,0674606_group_024_zh_cn,0733782_group_002_zh_cn,0754357_group_002_zh_cn,0490113_group_015_zh_cn,0798110_group_001_zh_cn,0766156_group_006_zh_cn,0189626_group_001_zh_cn,0766728_group_004_zh_cn",
"0674606024":"dam",
"0733782002":"dam",
"0754357002":"dam",
"0490113015":"manual",
"0798110001":"manual",
"0766156006":"manual",
"0189626001":"manual",
"0766728004":"manual",
"selection": false,
"description": "\u67D4\u8F6F\u536B\u8863\u9762\u6599\u77ED\u6B3E\u4E0A\u8863\uFF0C\u9970\u5370\u82B1\u56FE\u6848\uFF0C\u8863\u5E3D\u6709\u6C57\u5E03\u886C\u91CC\u548C\u62BD\u7EF3\u3002\u843D\u80A9\u957F\u8896\u8BBE\u8BA1\uFF0C\u7F57\u7EB9\u8896\u53E3\u53CA\u4E0B\u6446\u3002\u67D4\u8F6F\u62C9\u7ED2\u5185\u91CC\u3002",
"images":[
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/96/0a/960a537caa925f89d2e931ad6b7e890290bf72e9.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/96/0a/960a537caa925f89d2e931ad6b7e890290bf72e9.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/96/0a/960a537caa925f89d2e931ad6b7e890290bf72e9.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/96/0a/960a537caa925f89d2e931ad6b7e890290bf72e9.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/96/0a/960a537caa925f89d2e931ad6b7e890290bf72e9.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/96/0a/960a537caa925f89d2e931ad6b7e890290bf72e9.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/96/0a/960a537caa925f89d2e931ad6b7e890290bf72e9.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/d2/ea/d2ea54635d3cccb0367a656f8e3577162c4b0aef.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/d2/ea/d2ea54635d3cccb0367a656f8e3577162c4b0aef.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/d2/ea/d2ea54635d3cccb0367a656f8e3577162c4b0aef.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/d2/ea/d2ea54635d3cccb0367a656f8e3577162c4b0aef.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/d2/ea/d2ea54635d3cccb0367a656f8e3577162c4b0aef.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/d2/ea/d2ea54635d3cccb0367a656f8e3577162c4b0aef.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/d2/ea/d2ea54635d3cccb0367a656f8e3577162c4b0aef.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/e8/92/e8923f907ff0912e9838365cf8dbc99ccda4ec07.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/e8/92/e8923f907ff0912e9838365cf8dbc99ccda4ec07.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/e8/92/e8923f907ff0912e9838365cf8dbc99ccda4ec07.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/e8/92/e8923f907ff0912e9838365cf8dbc99ccda4ec07.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/e8/92/e8923f907ff0912e9838365cf8dbc99ccda4ec07.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/e8/92/e8923f907ff0912e9838365cf8dbc99ccda4ec07.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/e8/92/e8923f907ff0912e9838365cf8dbc99ccda4ec07.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/81/82/818220ae611f8c16f18132adaf4316d8ef01b548.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/81/82/818220ae611f8c16f18132adaf4316d8ef01b548.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/81/82/818220ae611f8c16f18132adaf4316d8ef01b548.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/81/82/818220ae611f8c16f18132adaf4316d8ef01b548.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/81/82/818220ae611f8c16f18132adaf4316d8ef01b548.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/81/82/818220ae611f8c16f18132adaf4316d8ef01b548.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/81/82/818220ae611f8c16f18132adaf4316d8ef01b548.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
}
],
"video": {
},
"sizes":[
{
"sizeCode": "0754698001001",
"size": "001",
"name": "155/76A(EUR XXS)"
}
,
{
"sizeCode": "0754698001002",
"size": "002",
"name": "160/80A(EUR XS)"
}
,
{
"sizeCode": "0754698001003",
"size": "003",
"name": "165/88A(EUR S)"
}
,
{
"sizeCode": "0754698001004",
"size": "004",
"name": "170/96A(EUR M)"
}
,
{
"sizeCode": "0754698001005",
"size": "005",
"name": "175/104A(EUR L)"
}
,
{
"sizeCode": "0754698001006",
"size": "006",
"name": "175/116A(EUR XL)"
}
],
"whitePrice": "¥199.00",
"whitePriceValue": "199.0",
"promoMarkerIcon": "",
"priceClub": null,
"concept": [
"DIVIDED"
],
"scenario_1": true,
"compositions": [
"\u5F39\u529B\u7F57\u7EB9: \u68C9 55%, \u805A\u916F\u7EA4\u7EF4 40%, \u6C28\u7EB6 5%",
"\u68C9 52%, \u805A\u916F\u7EA4\u7EF4 48%"
],
"composition": [
{
"compositionType" : "弹力罗纹",
"materials" :[
{
"name":"\u68C9",
"amount":"55%"
}
,
{
"name":"\u805A\u916F\u7EA4\u7EF4",
"amount":"40%"
}
,
{
"name":"\u6C28\u7EB6",
"amount":"5%"
}
]
},
{
"compositionType" : "",
"materials" :[
{
"name":"\u68C9",
"amount":"52%"
}
,
{
"name":"\u805A\u916F\u7EA4\u7EF4",
"amount":"48%"
}
]
}
],
"careInstructions": [
"40\u00B0\u673A\u6D17"
],
"detailedDescriptions": [
"\u6D45\u7C73\u8272"
],
"url": "/zh_cn/productpage.0754698001.html",
"productTransparencyEnabled":false,
"comingSoon":false,
"suppliersDetailEnabled":true,
"suppliersSectionDisabledReason":""
},
"0754698002": {
"name": "\u9ED1\u8272\/E.T.",
"inStore": false,
"energyClass": "",
"energyClassInterval": "",
"energyClassCode": "",
"energyClassIntervalCode": "",
"colorCode": "09",
"totalStyleWithArticles": "8",
"styleWithDefaultArticles":"0756787003,0411413002,0622958003,0721266001,0732409013,0778486001,0765545005,0448509001",
"productsWithStyleWith":"0754698_group_003_zh_cn,0756787_group_003_zh_cn,0411413_group_002_zh_cn,0622958_group_003_zh_cn,0721266_group_001_zh_cn,0732409_group_013_030_039_zh_cn,0778486_group_001_zh_cn,0765545_group_005_zh_cn,0448509_group_001_zh_cn",
"0756787003":"dam",
"0411413002":"dam",
"0622958003":"dam",
"0721266001":"manual",
"0732409013":"manual",
"0778486001":"manual",
"0765545005":"manual",
"0448509001":"manual",
"selection": false,
"description": "\u67D4\u8F6F\u536B\u8863\u9762\u6599\u77ED\u6B3E\u4E0A\u8863\uFF0C\u9970\u5370\u82B1\u56FE\u6848\uFF0C\u8863\u5E3D\u6709\u6C57\u5E03\u886C\u91CC\u548C\u62BD\u7EF3\u3002\u843D\u80A9\u957F\u8896\u8BBE\u8BA1\uFF0C\u7F57\u7EB9\u8896\u53E3\u53CA\u4E0B\u6446\u3002\u67D4\u8F6F\u62C9\u7ED2\u5185\u91CC\u3002",
"images":[
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/2a/f1/2af101ecad94fe287be5175f2463bb8854481d82.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/2a/f1/2af101ecad94fe287be5175f2463bb8854481d82.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/2a/f1/2af101ecad94fe287be5175f2463bb8854481d82.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/2a/f1/2af101ecad94fe287be5175f2463bb8854481d82.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/2a/f1/2af101ecad94fe287be5175f2463bb8854481d82.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/2a/f1/2af101ecad94fe287be5175f2463bb8854481d82.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/2a/f1/2af101ecad94fe287be5175f2463bb8854481d82.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/ec/47/ec47b0258a92f2ba6ec204dc69b5a70275f64a5c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/ec/47/ec47b0258a92f2ba6ec204dc69b5a70275f64a5c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/ec/47/ec47b0258a92f2ba6ec204dc69b5a70275f64a5c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/ec/47/ec47b0258a92f2ba6ec204dc69b5a70275f64a5c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/ec/47/ec47b0258a92f2ba6ec204dc69b5a70275f64a5c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/ec/47/ec47b0258a92f2ba6ec204dc69b5a70275f64a5c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/ec/47/ec47b0258a92f2ba6ec204dc69b5a70275f64a5c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/fd/89/fd898e9c1859e6ab73b9d4cd54da3142e8420e9a.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/fd/89/fd898e9c1859e6ab73b9d4cd54da3142e8420e9a.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/fd/89/fd898e9c1859e6ab73b9d4cd54da3142e8420e9a.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/fd/89/fd898e9c1859e6ab73b9d4cd54da3142e8420e9a.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/fd/89/fd898e9c1859e6ab73b9d4cd54da3142e8420e9a.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/fd/89/fd898e9c1859e6ab73b9d4cd54da3142e8420e9a.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/fd/89/fd898e9c1859e6ab73b9d4cd54da3142e8420e9a.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/76/28/76281a08471d710170735e063960bc1f1b12ea22.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/76/28/76281a08471d710170735e063960bc1f1b12ea22.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/76/28/76281a08471d710170735e063960bc1f1b12ea22.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/76/28/76281a08471d710170735e063960bc1f1b12ea22.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/76/28/76281a08471d710170735e063960bc1f1b12ea22.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/76/28/76281a08471d710170735e063960bc1f1b12ea22.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/76/28/76281a08471d710170735e063960bc1f1b12ea22.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/49/0b/490bddaf3c45e427061e0754d1cd61c02318ca30.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/49/0b/490bddaf3c45e427061e0754d1cd61c02318ca30.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/49/0b/490bddaf3c45e427061e0754d1cd61c02318ca30.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/49/0b/490bddaf3c45e427061e0754d1cd61c02318ca30.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/49/0b/490bddaf3c45e427061e0754d1cd61c02318ca30.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/49/0b/490bddaf3c45e427061e0754d1cd61c02318ca30.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/49/0b/490bddaf3c45e427061e0754d1cd61c02318ca30.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
}
],
"video": {
},
"sizes":[
{
"sizeCode": "0754698002001",
"size": "001",
"name": "155/76A(EUR XXS)"
}
,
{
"sizeCode": "0754698002002",
"size": "002",
"name": "160/80A(EUR XS)"
}
,
{
"sizeCode": "0754698002003",
"size": "003",
"name": "165/88A(EUR S)"
}
,
{
"sizeCode": "0754698002004",
"size": "004",
"name": "170/96A(EUR M)"
}
,
{
"sizeCode": "0754698002005",
"size": "005",
"name": "175/104A(EUR L)"
}
,
{
"sizeCode": "0754698002006",
"size": "006",
"name": "175/116A(EUR XL)"
}
],
"whitePrice": "¥199.00",
"whitePriceValue": "199.0",
"promoMarkerIcon": "",
"priceClub": null,
"concept": [
"DIVIDED"
],
"scenario_1": true,
"compositions": [
"\u5F39\u529B\u7F57\u7EB9: \u68C9 55%, \u805A\u916F\u7EA4\u7EF4 40%, \u6C28\u7EB6 5%",
"\u68C9 60%, \u805A\u916F\u7EA4\u7EF4 40%"
],
"composition": [
{
"compositionType" : "弹力罗纹",
"materials" :[
{
"name":"\u68C9",
"amount":"55%"
}
,
{
"name":"\u805A\u916F\u7EA4\u7EF4",
"amount":"40%"
}
,
{
"name":"\u6C28\u7EB6",
"amount":"5%"
}
]
},
{
"compositionType" : "",
"materials" :[
{
"name":"\u68C9",
"amount":"60%"
}
,
{
"name":"\u805A\u916F\u7EA4\u7EF4",
"amount":"40%"
}
]
}
],
"careInstructions": [
"40\u00B0\u673A\u6D17"
],
"detailedDescriptions": [
"\u9ED1\u8272\/\u84DD\u8272",
"A Steven Speilberg film, E.T., The extra-terrestrial in his adventure on earth"
],
"url": "/zh_cn/productpage.0754698002.html",
"productTransparencyEnabled":false,
"comingSoon":false,
"suppliersDetailEnabled":true,
"suppliersSectionDisabledReason":"",
"modelHeight":"170cm%2F5%277%22",
"garmentSize":"0754698002003",
},
"0754698003": {
"name": "\u5976\u6CB9\u8272\/Selena Gomez",
"inStore": false,
"energyClass": "",
"energyClassInterval": "",
"energyClassCode": "",
"energyClassIntervalCode": "",
"colorCode": "10",
"totalStyleWithArticles": "13",
"styleWithDefaultArticles":"0615970004,0799042001,0740211002,0791512001,0771942004,0806847001,0799365005,0662592002,0793732002,0795552002,0799044001,0794983001,0838783001",
"productsWithStyleWith":"0754698_group_003_zh_cn,0615970_group_004_zh_cn,0799042_group_001_zh_cn,0740211_group_002_zh_cn,0791512_group_001_zh_cn,0771942_group_004_zh_cn,0806847_group_001_zh_cn,0799365_group_005_zh_cn,0662592_group_002_zh_cn,0793732_group_002_zh_cn,0795552_group_002_zh_cn,0799044_zh_cn,0794983_group_001_zh_cn,0838783_group_001_zh_cn",
"0615970004":"dam",
"0799042001":"dam",
"0740211002":"manual",
"0791512001":"manual",
"0771942004":"manual",
"0806847001":"manual",
"0799365005":"manual",
"0662592002":"manual",
"0793732002":"manual",
"0795552002":"manual",
"0799044001":"manual",
"0794983001":"manual",
"0838783001":"manual",
"selection": "新品",
"description": "\u67D4\u8F6F\u536B\u8863\u9762\u6599\u77ED\u6B3E\u4E0A\u8863\uFF0C\u9970\u5370\u82B1\u56FE\u6848\uFF0C\u8863\u5E3D\u6709\u6C57\u5E03\u886C\u91CC\u548C\u62BD\u7EF3\u3002\u843D\u80A9\u957F\u8896\u8BBE\u8BA1\uFF0C\u7F57\u7EB9\u8896\u53E3\u53CA\u4E0B\u6446\u3002\u67D4\u8F6F\u62C9\u7ED2\u5185\u91CC\u3002",
"images":[
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/a0/58/a05899fedb3c101d2c44250cae50eee52e40c21c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/a0/58/a05899fedb3c101d2c44250cae50eee52e40c21c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/a0/58/a05899fedb3c101d2c44250cae50eee52e40c21c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/a0/58/a05899fedb3c101d2c44250cae50eee52e40c21c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/a0/58/a05899fedb3c101d2c44250cae50eee52e40c21c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/a0/58/a05899fedb3c101d2c44250cae50eee52e40c21c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/a0/58/a05899fedb3c101d2c44250cae50eee52e40c21c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/3d/79/3d792a5c821df1a38b8d750093d24bc5b953a85f.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/3d/79/3d792a5c821df1a38b8d750093d24bc5b953a85f.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/3d/79/3d792a5c821df1a38b8d750093d24bc5b953a85f.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/3d/79/3d792a5c821df1a38b8d750093d24bc5b953a85f.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/3d/79/3d792a5c821df1a38b8d750093d24bc5b953a85f.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/3d/79/3d792a5c821df1a38b8d750093d24bc5b953a85f.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/3d/79/3d792a5c821df1a38b8d750093d24bc5b953a85f.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/1c/bd/1cbdbfc57f46c37917a9e0eae3c9d915befd684c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/1c/bd/1cbdbfc57f46c37917a9e0eae3c9d915befd684c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/1c/bd/1cbdbfc57f46c37917a9e0eae3c9d915befd684c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/1c/bd/1cbdbfc57f46c37917a9e0eae3c9d915befd684c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/1c/bd/1cbdbfc57f46c37917a9e0eae3c9d915befd684c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/1c/bd/1cbdbfc57f46c37917a9e0eae3c9d915befd684c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/1c/bd/1cbdbfc57f46c37917a9e0eae3c9d915befd684c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[LOOKBOOK],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/9e/a4/9ea4058784c330684cdba47712f976baea040f00.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/9e/a4/9ea4058784c330684cdba47712f976baea040f00.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/9e/a4/9ea4058784c330684cdba47712f976baea040f00.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/9e/a4/9ea4058784c330684cdba47712f976baea040f00.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/9e/a4/9ea4058784c330684cdba47712f976baea040f00.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/9e/a4/9ea4058784c330684cdba47712f976baea040f00.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/9e/a4/9ea4058784c330684cdba47712f976baea040f00.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVESTILLLIFE],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
},
{
"thumbnail": "//lp2.hm.com/hmgoepprod?set=source[/76/6d/766df44560909dd622d2299f9942b4076a39929c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/thumb]",
"image": "//lp2.hm.com/hmgoepprod?set=source[/76/6d/766df44560909dd622d2299f9942b4076a39929c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/main]" : "//lp2.hm.com/hmgoepprod?set=source[/76/6d/766df44560909dd622d2299f9942b4076a39929c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/mobilemain]",
"fullscreen": "//lp2.hm.com/hmgoepprod?set=source[/76/6d/766df44560909dd622d2299f9942b4076a39929c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/fullscreen]" : "//lp2.hm.com/hmgoepprod?set=source[/76/6d/766df44560909dd622d2299f9942b4076a39929c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]",
"zoom": "//lp2.hm.com/hmgoepprod?set=source[/76/6d/766df44560909dd622d2299f9942b4076a39929c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/zoom]&zoom=zoom" : "//lp2.hm.com/hmgoepprod?set=source[/76/6d/766df44560909dd622d2299f9942b4076a39929c.jpg],origin[dam],category[ladies_hoodiesswetshirts_hoodies],type[DESCRIPTIVEDETAIL],res[m],hmver[1]&call=url[file:/product/mobilefullscreen]&zoom=zoom"
}
],
"video": {
},
"sizes":[
{
"sizeCode": "0754698003001",
"size": "001",
"name": "155/76A(EUR XXS)"
}
,
{
"sizeCode": "0754698003002",
"size": "002",
"name": "160/80A(EUR XS)"
}
,
{
"sizeCode": "0754698003003",
"size": "003",
"name": "165/88A(EUR S)"
}
,
{
"sizeCode": "0754698003004",
"size": "004",
"name": "170/96A(EUR M)"
}
,
{
"sizeCode": "0754698003005",
"size": "005",
"name": "175/104A(EUR L)"
}
,
{
"sizeCode": "0754698003006",
"size": "006",
"name": "175/116A(EUR XL)"
}
],
"whitePrice": "¥199.00",
"whitePriceValue": "199.0",
"promoMarkerIcon": "",
"priceClub": null,
"concept": [
"DIVIDED"
],
"scenario_1": true,
"compositions": [
"\u68C9 60%, \u805A\u916F\u7EA4\u7EF4 40%"
],
"composition": [
{
"compositionType" : "",
"materials" :[
{
"name":"\u68C9",
"amount":"60%"
}
,
{
"name":"\u805A\u916F\u7EA4\u7EF4",
"amount":"40%"
}
]
}
],
"careInstructions": [
"40\u00B0\u673A\u6D17"
],
"detailedDescriptions": [
"\u5976\u6CB9\u8272\/\u9ED1\u8272\/\u7D2B\u8272",
"Selena Gomez"
],
"url": "/zh_cn/productpage.0754698003.html",
"productTransparencyEnabled":false,
"comingSoon":false,
"suppliersDetailEnabled":true,
"suppliersSectionDisabledReason":"",
"modelHeight":"174cm%2F5%279%22",
"garmentSize":"0754698003003",
}
}
\ No newline at end of file
......@@ -21,35 +21,6 @@
> 注意爬虫的命名
# 爬虫步骤
## 目的
帮助不能使用国内购物平台的用户进行**代购服务**,而要进行代购,就要**帮助他们下单**。为了帮助用户下单,很重要的
一步就是要**获取平台的商品的规格**;让用户可以在浏览的时候,可以让他们在我们app上选择相应规格的商品
## 分析页面数据
首先要明白的是:App页面传给我们的只有原始商品的连接,为了获取页面上的商品信息有两种方式:
- 分析**页面**构成,例如:Zara 爬虫
- 在某个地方会存在json数据的传递
- 嵌套在Html页面中的各种数据
- 分析页面调用接口后的返回数据,例如:Uniqlo 优衣库爬虫
## 页面中存在Json数据传递的--示例:Zara
### 1.随便点击一个商品详情页<br>
![](img/zara商品页.png)
### 2.通过商品的一些关键信息进行搜索<br>
![](img/zara关键子搜索.png)
### 3.检索信息(关键步骤)
- (1) **感觉可能**这是相关的商品详情信息,而且是**Json格式**的数据
- (2) 通过[Json格式化工具:http://www.bejson.com/jsonviewernew/](http://www.bejson.com/jsonviewernew/)来格式化Json数据
- (3) 再次通过关键搜索诸如**价格****尺寸**等,检查数据是否是我们想要的、是否是完整的,如果不是重复(1)、(2)步骤继续搜寻<br>
![](img/zara截取的数据.png)
- (4) 确认完数据后查看该 json 的id名是什么<br>
- Zara传递的这个Json的id是**dataLayer**<br>
![](img/Zara爬虫05.png)
### 4.截取数据封装数据
- 新键该爬虫,请看**添加新爬虫至项目规范**
- [ZaraSpider.java](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/ZaraSpider.java)
- 如何处理数据详情请看爬虫的@see注释
# 需要爬取的购物网站
### [Pull and Bear](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/PullandbearSpider.java)
- 主页:https://www.pullandbear.cn/cn/%E5%A5%B3%E5%A3%AB-c1030204574.html
......@@ -74,10 +45,11 @@
- 主页:https://www.nike.com/cn
- 命名:nike
- 爬虫进度:**已完成**
### Adidas
### [Adidas](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/AdidasSpider.java)
- 主页:https://www.adidas.com.cn/
- 命名:adidas
- 爬虫进度:数据嵌在HTML中
- 爬虫进度:**已完成**
### H&M
- 主页:https://www2.hm.com/zh_cn/
- 命名:hm
......@@ -87,27 +59,32 @@
### LiLy
- 主页:http://www.lily.sh.cn/webapp/wcs/stores/servlet/lilystore
- 命名:lily
- 爬虫进度:数据嵌在HTML中
- 爬虫进度:已完成分析,待处理
- 数据嵌在HTML中,数据较难处理,延后爬取
### Eifini
- 主页:https://eifini.tmall.com/
- 命名:eifini
- 爬虫进度:
### Urban Revivo
- 爬虫进度:未知方法
- 该购物网站是天猫代理的商城
### [Urban Revivo](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/UrbanRevivoSpider.java)
- 主页:http://www.ur.cn/index.html
- 命名:ur
- 爬虫进度:
### Aber Crombie
- 命名:urbanrevivo
- 爬虫进度:**已完成**
- 商品案例:http://wap.ur.com.cn/product/detail?productColorId=ff8080816dbb693e016dfd58f27c45d9
- 数据接口:http://wap.ur.com.cn/product/product/detail?id=ff8080816dbb693e016dfd58f27c45d9
### Aber Crombie & Fitch
- 主页:https://www.abercrombie.cn/zh_CN/home
- 命名:abercrombie
- 爬虫进度:
### Under Armour
- 爬虫进度:存在反爬机制
- 链接做了编码形式的反爬机制
### [Under Armour](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/UnderArmourSpider.java)
- 主页:https://www.underarmour.cn/
- 命名:ur
- 爬虫进度:
### converse
- 爬虫进度:**已完成**
### Converse 匡威
- 主页:https://www.converse.com.cn/
- 命名:converse
- 爬虫进度:
- 爬虫进度:存在反向代理的反爬机制,暂无法爬取
### Ochirly
- 主页:http://www.ochirly.com.cn/SALE/list.shtml
- 命名:ochirly
......@@ -161,6 +138,41 @@
- 32,https://www.apple.com/cn/shop/buy-iphone/iphone-xr
- 33,https://www.louisvuitton.cn/zhs-cn/homepage?campaign=sem_CN_ZHS_BA_EC_BZON_PC_Valuable_H1_homepage
# 爬虫步骤
## 目的
帮助不能使用国内购物平台的用户进行**代购服务**,而要进行代购,就要**帮助他们下单**。为了帮助用户下单,很重要的
一步就是要**获取平台的商品的规格**;让用户可以在浏览的时候,可以让他们在我们app上选择相应规格的商品
## 分析页面数据
首先要明白的是:App页面传给我们的只有原始商品的连接,为了获取页面上的商品信息有两种方式:
- 分析**页面**构成,例如:Zara 爬虫
- 在某个地方会存在json数据的传递
- 嵌套在Html页面中的各种数据
- 分析页面调用接口后的返回数据,例如:Uniqlo 优衣库爬虫
## 页面中存在Json数据传递的--示例:Zara
### 1.随便点击一个商品详情页<br>
![](img/zara商品页.png)
### 2.通过商品的一些关键信息进行搜索<br>
![](img/zara关键子搜索.png)
### 3.检索信息(关键步骤)
- (1) **感觉可能**这是相关的商品详情信息,而且是**Json格式**的数据
- (2) 通过[Json格式化工具:http://www.bejson.com/jsonviewernew/](http://www.bejson.com/jsonviewernew/)来格式化Json数据
- (3) 再次通过关键搜索诸如**价格****尺寸**等,检查数据是否是我们想要的、是否是完整的,如果不是重复(1)、(2)步骤继续搜寻<br>
![](img/zara截取的数据.png)
- (4) 确认完数据后查看该 json 的id名是什么<br>
- Zara传递的这个Json的id是**dataLayer**<br>
![](img/Zara爬虫05.png)
### 4.截取数据封装数据
- 新键该爬虫,请看**添加新爬虫至项目规范**
- [ZaraSpider.java](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/ZaraSpider.java)
- 如何处理数据详情请看爬虫的@see注释
# Java 处理爬取的数据
## Json 数据的处理
## HTML 数据的处理
# 爬虫Json数据返回规范
## 封装类 [ProductResponse](../src/main/java/com/diaoyun/zion/chinafrica/vo/ProductResponse.java)
......
package com.diaoyun.zion;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication
@EnableCaching
......@@ -19,7 +19,9 @@ public class ZionApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ZionApplication.class, args);
}
@Test
public void test() throws Exception{
}
}
......@@ -10,14 +10,21 @@ import java.util.concurrent.TimeoutException;
/**
* 商品爬虫接口
*
* @author G
*/
public interface IItemSpider {
/**
* 爬取商品数据
* @param targetUrl
* @return
* @param targetUrl 商品详情页路径
* @return 返回格式化及翻译后的 Json 数据
* @throws InterruptedException 被打断异常
* @throws IOException IO异常
* @throws ExecutionException 运行时异常
* @throws URISyntaxException 语法异常
* @throws TimeoutException 超时异常
*/
JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException;
JSONObject captureItem(String targetUrl) throws InterruptedException, IOException, ExecutionException, URISyntaxException, TimeoutException;
}
......@@ -2,8 +2,10 @@ package com.diaoyun.zion.chinafrica.bis.impl;
import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.ProductResponse;
import com.diaoyun.zion.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.SpiderUtil;
import com.diaoyun.zion.master.util.TranslateHelper;
import com.diaoyun.zion.master.util.spider.AdidasSpiderParse;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -25,29 +27,31 @@ public class AdidasSpider implements IItemSpider {
private static Logger logger = LoggerFactory.getLogger(PullandbearSpider.class);
/**
* Adidas 商品详情页连接
* Adidas 商品详情页 Url
*/
private static final String ADIDAS_URL="https://www.adidas.com.cn/item";
/**
* Adidas 数据爬虫
* @see com.diaoyun.zion.chinafrica.service.impl.SpiderServiceImpl#judgeUrlType 修改商品详情页路径
* @see SpiderUtil#formatPullAndBearProductResponse 格式化数据方法
* @see AdidasSpiderParse#formatProductResponse 格式化数据方法
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
*/
@Override
public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException {
JSONObject resultJson = JSONObject.fromObject(targetUrl);
// 截取商品的 id
int labelHeadIndex = targetUrl.indexOf("item/");
int labelTailIndex = targetUrl.lastIndexOf("?");
String pId = targetUrl.substring(labelHeadIndex, labelTailIndex).replace("item/", "");
// 对应的商品数据接口
targetUrl = "https://www.adidas.com.cn/item/othercolor?itemCode=" + pId;
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.ADIDAS.getValue());
// 格式化商品数据
ProductResponse productResponse = AdidasSpiderParse.formatProductResponse(content, pId);
JSONObject resultJson = JSONObject.fromObject(productResponse);
// 翻译
TranslateHelper.translateProductResponse(resultJson);
return resultJson;
}
public static void main(String[] args) throws Exception {
String targetUrl = "";
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.ADIDAS.getValue());
System.out.println(content);
}
}
......@@ -5,7 +5,7 @@ import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.ProductResponse;
import com.diaoyun.zion.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.JsoupUtil;
import com.diaoyun.zion.master.util.SpiderUtil;
import com.diaoyun.zion.master.util.spider.SpiderUtil;
import com.diaoyun.zion.master.util.TranslateHelper;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
......
package com.diaoyun.zion.chinafrica.bis.impl;
public class EspritSpider {
}
......@@ -3,6 +3,7 @@ package com.diaoyun.zion.chinafrica.bis.impl;
import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.vo.ProductResponse;
import com.diaoyun.zion.master.util.*;
import com.diaoyun.zion.master.util.spider.SpiderUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
......@@ -15,6 +16,8 @@ import java.util.concurrent.TimeoutException;
/**
* Gap数据爬虫
*
* TOTO 不可用
*/
@Component("gapItemSpider")
public class GapItemSpider implements IItemSpider {
......
package com.diaoyun.zion.chinafrica.bis.impl;
public class LeviSpider {
}
package com.diaoyun.zion.chinafrica.bis.impl;
import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.spider.LilySpiderParse;
import net.sf.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/**
* Lily 数据爬虫
*
* TODO 数据已分析,难度较大,延后处理
*
* @author 爱酱油不爱醋
*/
@Component("lilySpider")
public class LilySpider implements IItemSpider {
private static Logger logger = LoggerFactory.getLogger(PullandbearSpider.class);
/**
* Lily 商品详情页 Url
*/
private static final String ADIDAS_URL="http://www.lily.sh.cn/webapp/wcs/stores/servlet/lilystore";
/**
* Lily 数据爬虫
* @see LilySpiderParse#formatProductResponse 格式化数据方法
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
*/
@Override
public JSONObject captureItem(String targetUrl) throws InterruptedException, IOException, ExecutionException, URISyntaxException, TimeoutException {
return null;
}
public static void main(String[] args) throws Exception {
String targetUrl = "http://www.lily.sh.cn/webapp/wcs/stores/servlet/lilystore/24003/276409";
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.LILY.getValue());
Document document = Jsoup.parse(content);
System.out.println(content);
System.err.println(document);
}
}
......@@ -4,8 +4,8 @@ import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.ProductResponse;
import com.diaoyun.zion.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.JsoupUtil;
import com.diaoyun.zion.master.util.SpiderUtil;
import com.diaoyun.zion.master.util.spider.MassimoDuttiSpiderParse;
import com.diaoyun.zion.master.util.spider.SpiderUtil;
import com.diaoyun.zion.master.util.TranslateHelper;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
......@@ -20,8 +20,7 @@ import java.util.concurrent.TimeoutException;
/**
* Massimo Dutti 数据爬虫
*
* https://www.massimodutti.cn/cn/%E5%A5%B3%E8%A3%85/corners/denim/%E4%B8%AD%E8%85%B0%E8%8E%B1%E8%B5%9B%E5%B0%94%E6%A3%89%E8%B4%A8%E7%9B%B4%E7%AD%92%E9%95%BF%E8%A3%A4-c1855082p8667556.html?colorId=712&categoryId=1855082
* https://www.massimodutti.cn/cn/%E5%A5%B3%E8%A3%85/corners/denim/%E4%B8%AD%E8%85%B0%E8%8E%B1%E8%B5%9B%E5%B0%94%E6%A3%89%E8%B4%A8%E7%9B%B4%E7%AD%92%E9%95%BF%E8%A3%A4-c1855082p8667556.html?colorId=712&categoryId=1855082
* TODO App中路径传递存在一定的问题
*
* @author 爱酱油不爱醋
*/
......@@ -37,8 +36,7 @@ public class MassimoduttiSpider implements IItemSpider {
/**
* Massimo Dutti 数据爬虫
* @see com.diaoyun.zion.chinafrica.service.impl.SpiderServiceImpl#judgeUrlType 修改商品详情页路径
* @see SpiderUtil#formatMassimoDuttiProductResponse 格式化数据方法
* @see MassimoDuttiSpiderParse#formatProductResponse 格式化数据方法
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
*/
......@@ -52,7 +50,7 @@ public class MassimoduttiSpider implements IItemSpider {
String dataUrl = "https://www.massimodutti.cn/itxrest/2/catalog/store/35009478/30359500/category/0/product/" + pId + "/detail?languageId=-7&appId=1";
String content = HttpClientUtil.getContentByUrl(dataUrl, PlatformEnum.MASSIMODUTTI.getValue());
JSONObject resultObj = JSONObject.fromObject(content);
ProductResponse productResponse = SpiderUtil.formatMassimoDuttiProductResponse(resultObj, pId);
ProductResponse productResponse = MassimoDuttiSpiderParse.formatProductResponse(resultObj, pId);
resultObj = JSONObject.fromObject(productResponse);
TranslateHelper.translateProductResponse(resultObj);
return resultObj;
......
package com.diaoyun.zion.chinafrica.bis.impl;
public class MocoSpider {
}
......@@ -4,6 +4,7 @@ import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.ProductResponse;
import com.diaoyun.zion.master.util.*;
import com.diaoyun.zion.master.util.spider.SpiderUtil;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......
package com.diaoyun.zion.chinafrica.bis.impl;
import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.ProductResponse;
import com.diaoyun.zion.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.TranslateHelper;
import com.diaoyun.zion.master.util.spider.OchirlySpiderParse;
import net.sf.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/**
* OchirlySpider 数据爬虫
* TODO 存在"暂时无货"的判断
* @author 爱酱油不爱醋
*/
@Component("ochirlySpider")
public class OchirlySpider implements IItemSpider {
private static Logger logger = LoggerFactory.getLogger(ZaraSpider.class);
/**
* OchirlySpider 商品详情页Url
*/
private static final String URBANREVIVO_URL = "http://www.ochirly.com.cn/p/mobile/";
/**
* 爬虫数据返回
* @see OchirlySpiderParse#formatProductResponse 格式化方法
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
* @see
*/
@Override
public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException {
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.UNDERARMOUR.getValue());
ProductResponse productResponse = OchirlySpiderParse.formatProductResponse(content);
JSONObject resultObj = JSONObject.fromObject(productResponse);
// 翻译
TranslateHelper.translateProductResponse(resultObj);
return resultObj;
}
public static void main(String[] args) throws Exception {
String targetUrl = "http://www.ochirly.com.cn/p/mobile/1ZY4070820410.shtml";
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.UNDERARMOUR.getValue());
Document document = Jsoup.parse(content);
// 获取标题
Elements detailEle = document.select("div[class=detail]").select("div[class=desc]");
String pTitle = detailEle.select("h5").text();
System.err.println(pTitle);
// 获取价格
Elements priceEle = detailEle.select("p[class=price]");
String pPrice = priceEle.attr("data-list-price");
System.err.println(pPrice);
// 获取颜色id与图片
Elements colorEle = document.select("div[class=color]").select("ul[class=clearfix]");
List<String> imgUrlList = colorEle.select("a").eachAttr("href");
List<String> colorNoList = new ArrayList<>();
for (int i = 0; i < imgUrlList.size(); i++) {
String hrefStr = imgUrlList.get(i);
if (hrefStr.contains("/p/mobile/")) {
String[] spilt = hrefStr.split("/mobile/");
colorNoList.add(spilt[1].replaceAll(".shtml", ""));
} else {
colorNoList.add(0, priceEle.attr("data-sku"));
}
}
System.err.println(colorNoList);
List<String> pImgList = colorEle.select("img").eachAttr("src");
System.err.println(pImgList);
// 获取尺码
Elements sizeEle = document.select("div[class=size]").select("div[class=size_contain]").select("li");
Elements delEle = sizeEle.select("del").remove();
System.out.println(delEle);
List<String> pSizeList = sizeEle.eachText();
List<String> pSizeNoList = sizeEle.eachAttr("data-size-id");
System.err.println(pSizeList);
System.err.println(pSizeNoList);
}
}
\ No newline at end of file
......@@ -4,9 +4,8 @@ import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.ProductResponse;
import com.diaoyun.zion.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.SpiderUtil;
import com.diaoyun.zion.master.util.spider.PullAndBearSpiderParse;
import com.diaoyun.zion.master.util.TranslateHelper;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -34,8 +33,7 @@ public class PullandbearSpider implements IItemSpider {
/**
* PullAndBear 数据爬虫
* @see com.diaoyun.zion.chinafrica.service.impl.SpiderServiceImpl#judgeUrlType 修改商品详情页路径
* @see SpiderUtil#formatPullAndBearProductResponse 格式化数据方法
* @see PullAndBearSpiderParse#formatProductResponse 格式化数据方法
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
*/
......@@ -45,7 +43,7 @@ public class PullandbearSpider implements IItemSpider {
targetUrl = PULL_AND_BEAR_URL + pId + "/detail?languageId=-7&appId=1";
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.PULLANDBEAR.getValue());
JSONObject resultJson = JSONObject.fromObject(content);
ProductResponse productResponse = SpiderUtil.formatPullAndBearProductResponse(resultJson, pId);
ProductResponse productResponse = PullAndBearSpiderParse.formatProductResponse(resultJson, pId);
resultJson = JSONObject.fromObject(productResponse);
// 翻译
TranslateHelper.translateProductResponse(resultJson);
......
package com.diaoyun.zion.chinafrica.bis.impl;
import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.ProductResponse;
import com.diaoyun.zion.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.TranslateHelper;
import com.diaoyun.zion.master.util.spider.UnderArmourSpiderParse;
import net.sf.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/**
* UnderArmour 数据爬虫
*
* @author 爱酱油不爱醋
*/
@Component("underarmourSpider")
public class UnderArmourSpider implements IItemSpider {
private static Logger logger = LoggerFactory.getLogger(ZaraSpider.class);
/**
* UnderArmour 商品详情页Url
*/
private static final String URBANREVIVO_URL = "https://www.underarmour.cn/p";
/**
* 爬虫数据返回
* @see UnderArmourSpiderParse#formatProductResponse 数据格式化
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
* @see
*/
@Override
public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException {
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.UNDERARMOUR.getValue());
ProductResponse productResponse = UnderArmourSpiderParse.formatProductResponse(content);
JSONObject resultObj = JSONObject.fromObject(productResponse);
// 翻译
TranslateHelper.translateProductResponse(resultObj);
return resultObj;
}
}
\ No newline at end of file
......@@ -4,9 +4,8 @@ import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.ProductResponse;
import com.diaoyun.zion.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.SpiderUtil;
import com.diaoyun.zion.master.util.TranslateHelper;
import net.sf.json.JSONArray;
import com.diaoyun.zion.master.util.spider.UniqloSpiderParse;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -33,8 +32,7 @@ public class UniqloSpider implements IItemSpider {
/**
* Uniqlo 数据爬虫
* @see com.diaoyun.zion.chinafrica.service.impl.SpiderServiceImpl#judgeUrlType 修改商品详情页路径
* @see SpiderUtil#formatUniqloProductResponse 格式化数据方法
* @see UniqloSpiderParse#formatProductResponse 格式化数据方法
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
*/
......@@ -50,7 +48,7 @@ public class UniqloSpider implements IItemSpider {
String priceContent = HttpClientUtil.getContentByUrl(priceUrl, PlatformEnum.UNIQLO.getValue());
JSONObject resultJson = JSONObject.fromObject(content);
JSONObject priceJson = JSONObject.fromObject(priceContent);
ProductResponse productResponse = SpiderUtil.formatUniqloProductResponse(resultJson, priceJson, pId);
ProductResponse productResponse = UniqloSpiderParse.formatProductResponse(resultJson, priceJson, pId);
resultJson = JSONObject.fromObject(productResponse);
// 翻译
TranslateHelper.translateProductResponse(resultJson);
......
package com.diaoyun.zion.chinafrica.bis.impl;
import com.diaoyun.zion.chinafrica.bis.IItemSpider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.ProductResponse;
import com.diaoyun.zion.master.util.HttpClientUtil;
import com.diaoyun.zion.master.util.TranslateHelper;
import com.diaoyun.zion.master.util.spider.UrbanRevivoSpiderParse;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/**
* UrbanRevivo 数据爬虫
*
* @author 爱酱油不爱醋
*/
@Component("urbanrevivoSpider")
public class UrbanRevivoSpider implements IItemSpider {
private static Logger logger = LoggerFactory.getLogger(ZaraSpider.class);
/**
* UrbanRevivo 商品详情页Url
*/
private static final String UrbanRevivo_URL = "http://wap.ur.com.cn/product/detail";
/**
* UrbanRevivo 数据爬虫
* @see UrbanRevivoSpiderParse#formatProductResponse 格式化数据方法
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
*/
@Override
public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException {
// 截取链接中商品的 id
String[] split = targetUrl.split("productColorId=");
String pId = split[1];
System.err.println(pId);
// 访问数据接口
targetUrl = "http://wap.ur.com.cn/product/product/detail?id=" + pId;
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.URBANREVIVO.getValue());
JSONObject resultObj = JSONObject.fromObject(content);
// 格式化数据
ProductResponse productResponse = UrbanRevivoSpiderParse.formatProductResponse(resultObj, pId);
resultObj = JSONObject.fromObject(productResponse);
// 翻译数据
TranslateHelper.translateProductResponse(resultObj);
return resultObj;
}
}
\ No newline at end of file
......@@ -17,8 +17,12 @@ public enum PlatformEnum implements EnumItemable<PlatformEnum> {
ZARA("Zara", "zara"),
UNIQLO("优衣库", "uniqlo"),
NIKE("NIKE", "nike"),
ADIDAS("Adidas", "adidas"),
ADIDAS("阿迪达斯", "adidas"),
HM("H&M", "hm"),
LILY("Lily", "lily"),
URBANREVIVO("UrbanRevivo", "urbanrevivo"),
UNDERARMOUR("安德玛", "underarmour"),
OCHIRLY("Ochirly", "ochirly"),
MASSIMODUTTI("MassimoDutti", "massimodutti"),
UN("未知", "un"),
AfriEshop("afri-eshop","afri-eshop" );
......
......@@ -12,52 +12,68 @@ public class ItemSpiderFactory {
public static IItemSpider getSpider(PlatformEnum platformEnum) {
IItemSpider iItemSpider;
switch (platformEnum.getValue()) {
case "tb":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("tbItemSpider");
case "tb": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("tbItemSpider");
break;
}
case "tm":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("tmItemSpider");
case "tm": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("tmItemSpider");
break;
}
case "pullandbear":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("pullandbearSpider");
case "pullandbear": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("pullandbearSpider");
break;
}
case "gap":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("gapItemSpider");
case "gap": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("gapItemSpider");
break;
}
case "zara":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("zaraSpider");
case "zara": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("zaraSpider");
break;
}
case "uniqlo":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("uniqloSpider");
case "uniqlo": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("uniqloSpider");
break;
}
case "nike":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("nikeItemSpider");
case "nike": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("nikeItemSpider");
break;
}
case "adidas":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("adidasSpider");
case "adidas": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("adidasSpider");
break;
}
case "hm":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("hmSpider");
case "hm": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("hmSpider");
break;
}
case "massimodutti":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("massimoduttiSpider");
case "lily": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("lilySpider");
break;
}
case "urbanrevivo": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("urbanrevivoSpider");
break;
}
case "underarmour": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("underarmourSpider");
break;
}
case "ochirly": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("ochirlySpider");
break;
}
case "massimodutti": {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("massimoduttiSpider");
break;
}
case "afri-eshop":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("africaShopItemSpider");
iItemSpider = (IItemSpider) SpringContextUtil.getBean("africaShopItemSpider");
break;
}
default:{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("emptyItemSpider");
default: {
iItemSpider = (IItemSpider) SpringContextUtil.getBean("emptyItemSpider");
break;
}
}
......
......@@ -53,17 +53,25 @@ public class SpiderServiceImpl implements SpiderService {
platformEnum=PlatformEnum.GAP;
} else if(targetUrl.contains("www.nike.com/cn/t/")) {
platformEnum=PlatformEnum.NIKE;
} else if(targetUrl.contains("https://www.adidas.com.cn/item")) {
platformEnum=PlatformEnum.ADIDAS;
} else if(targetUrl.contains("www.afri-eshop.com")&&targetUrl.contains("/products/")) {
platformEnum=PlatformEnum.AfriEshop;
} else if (targetUrl.contains("zara.cn")) {
platformEnum = PlatformEnum.ZARA;
} else if (targetUrl.contains("h.uniqlo.cn/#/product")) {
} else if (targetUrl.contains("h.uniqlo.cn/")) {
platformEnum = PlatformEnum.UNIQLO;
} else if (targetUrl.contains("hm.com/zh_cn/productpage")) {
platformEnum = PlatformEnum.HM;
} else if (targetUrl.contains("massimodutti.cn/") && targetUrl.contains("colorId") && targetUrl.contains("categoryId")) {
} else if(targetUrl.contains("https://www.adidas.com.cn/item")) {
platformEnum=PlatformEnum.ADIDAS;
} else if(targetUrl.contains("http://www.lily.sh.cn/webapp/wcs/stores/servlet/lilystore")) {
platformEnum=PlatformEnum.LILY;
} else if(targetUrl.contains("http://wap.ur.com.cn/product/detail")) {
platformEnum=PlatformEnum.URBANREVIVO;
} else if(targetUrl.contains("underarmour.cn/p")) {
platformEnum=PlatformEnum.UNDERARMOUR;
} else if(targetUrl.contains("ochirly.com.cn/p/mobile/")) {
platformEnum=PlatformEnum.OCHIRLY;
} else if (targetUrl.contains("massimodutti.cn") && targetUrl.contains("colorId") && targetUrl.contains("categoryId")) {
platformEnum = PlatformEnum.MASSIMODUTTI;
}
return platformEnum;
......
......@@ -111,7 +111,6 @@ public class HttpClientUtil {
return sibContent;
}
/**
* 创建带浏览器头部的连接
* @return
......@@ -151,7 +150,6 @@ public class HttpClientUtil {
return HttpClients.custom().setDefaultHeaders(headerList).setDefaultCookieStore(cookieStore).build();
}
/**
* 创建带苹果手机头部的连接
* @return
......
......@@ -85,14 +85,14 @@ public class JsoupUtil {
* @return
*/
public static String getScriptContent(String content, String variableName) {
//logger.info(content);
// logger.info(content);
Document document = Jsoup.parse(content);
Elements elementList = document.getElementsByTag("script");
String configGroup = null;
for (Element element : elementList) {
for (DataNode dataNode : element.dataNodes()) {
String dataStr = dataNode.getWholeData();
//获取带有 g_config 变量的 script 标签
// 获取带有 g_config 变量的 script 标签
Pattern p = Pattern.compile("(" + variableName + "){1,1}\\s*={1,1}[\\s\\S]*(;){1,1}"); // Regex for the value of the key
Matcher m = p.matcher(dataStr); // you have to use html here and NOT text! Text will drop the 'key' part
while ((m.find())) {
......@@ -157,7 +157,7 @@ public class JsoupUtil {
* @return
*/
public static Map<String, Object> getPropMap(String content) {
Map<String, Object> resultMap = new HashMap<>();
Map<String, Object> resultMap = new HashMap<>(16);
Document document = Jsoup.parse(content);
Element skuElement = document.getElementById("J_isku");
Elements propList = skuElement.getElementsByClass("J_Prop");
......@@ -231,18 +231,7 @@ public class JsoupUtil {
return dataMap;
}
/**
* 获取 Zara 爬虫的主要数据
* @param content
* @return
*/
public static JSONObject getZaraJsonData(String content) {
int labelHeadIndex = content.indexOf("dataLayer");
int labelTailIndex = content.lastIndexOf(";window.zara.viewPayload");
String abv = content.substring(labelHeadIndex, labelTailIndex).replace("dataLayer = ", "");
JSONObject dataMap= JSONObject.fromObject(abv);
return dataMap;
}
/**
* 获取 H&M 爬虫的主要数据
......
package com.diaoyun.zion.master.util.spider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.util.*;
import static com.diaoyun.zion.master.util.spider.SpiderUtil.exchangeRate;
/**
* Adidas 数据爬虫
* @see com.diaoyun.zion.chinafrica.bis.impl.AdidasSpider
* @author 爱酱油不爱醋
*/
public class AdidasSpiderParse {
/**
* 格式化返回数据
* @param content 主要的页面数据
* @return 格式化后的数据
*/
public static ProductResponse formatProductResponse(String content, String pId) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
// 解析为 Document 对象
Document document = Jsoup.parse(content);
// 获取商品的价格、颜色、标题、图片、尺码属性
String fullPrice = document.select("input[id=salePrice]").attr("value");
String pColor = document.select("input[id=colorDisPaly]").attr("value");
String pTitle = document.select("input[id=itemTitle]").attr("value");
String pImg = document.select("input[id=shoppingcartpic]").attr("value");
List<String> pSizeList = document.select("div[class=overview product-size]")
.select("ul").select("li").eachText();
//////////////////////////////////// 获取商品基本信息 ////////////////////////////
ItemInfo itemInfo = new ItemInfo();
itemInfo.setShopName(PlatformEnum.ADIDAS.getLabel());
itemInfo.setShopUrl("https://www.adidas.com");
itemInfo.setItemId(pId);
itemInfo.setTitle(pTitle);
itemInfo.setPic(pImg);
//////////////////////////////////// 获取商品基本信息End /////////////////////////
for (int i = 0; i < pSizeList.size(); i++) {
// 库存对应的id(颜色id + 尺码id)
String skuStr = ";" + pId + ";" + pSizeList.get(i) + ";";
///////////////////////// 获取商品尺码属性 ////////////////////
Set<ProductProp> sizePropSet = new HashSet<>();
ProductProp productPropSize = new ProductProp();
productPropSize.setPropId(pSizeList.get(i));
productPropSize.setPropName(pSizeList.get(i));
sizePropSet.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSet.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSet);
}
///////////////////////// 获取商品尺码属性 END////////////////////
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,Zara 未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
// TODO 转换汇率,目前商品单位是人民币
String originalFullPrice = exchangeRate(fullPrice);
originalPrice.setPrice(originalFullPrice);
productResponse.setPrice(originalFullPrice);
productResponse.setSalePrice(originalFullPrice + "-" + originalFullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END///////////////////////////////
}
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////
Set<ProductProp> propSet = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
// 颜色描述
productPropColor.setPropId(pId);
productPropColor.setPropName(pColor);
productPropColor.setImage(pImg);
propSet.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSet.addAll(oldPropSet);
productPropSet.put("颜色", propSet);
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.ADIDAS.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
}
package com.diaoyun.zion.master.util.spider;
public class EspritSpiderParse {
}
package com.diaoyun.zion.master.util.spider;
public class LeviSpiderParse {
}
package com.diaoyun.zion.master.util.spider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.util.*;
import static com.diaoyun.zion.master.util.spider.SpiderUtil.exchangeRate;
/**
* Lily 爬虫数据解析
* @see com.diaoyun.zion.chinafrica.bis.impl.LilySpider
* @author 爱酱油不爱醋
*/
public class LilySpiderParse {
public static ProductResponse formatProductResponse(String content, String pId) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
// 解析为 Document 对象
Document document = Jsoup.parse(content);
// 获取商品的价格、颜色、标题、图片、尺码属性
String fullPrice = document.select("input[id=salePrice]").attr("value");
String pColor = document.select("input[id=colorDisPaly]").attr("value");
String pTitle = document.select("input[id=itemTitle]").attr("value");
String pImg = document.select("input[id=shoppingcartpic]").attr("value");
List<String> pSizeList = document.select("div[class=overview product-size]")
.select("ul").select("li").eachText();
//////////////////////////////////// 获取商品基本信息 ////////////////////////////
ItemInfo itemInfo = new ItemInfo();
itemInfo.setShopName(PlatformEnum.ADIDAS.getLabel());
itemInfo.setShopUrl("https://www.adidas.com");
itemInfo.setItemId(pId);
itemInfo.setTitle(pTitle);
itemInfo.setPic(pImg);
//////////////////////////////////// 获取商品基本信息End /////////////////////////
for (int i = 0; i < pSizeList.size(); i++) {
// 库存对应的id(颜色id + 尺码id)
String skuStr = ";" + pId + ";" + pSizeList.get(i) + ";";
///////////////////////// 获取商品尺码属性 ////////////////////
Set<ProductProp> sizePropSet = new HashSet<>();
ProductProp productPropSize = new ProductProp();
productPropSize.setPropId(pSizeList.get(i));
productPropSize.setPropName(pSizeList.get(i));
sizePropSet.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSet.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSet);
}
///////////////////////// 获取商品尺码属性 END////////////////////
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,Zara 未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
// TODO 转换汇率,目前商品单位是人民币
fullPrice = exchangeRate(fullPrice);
originalPrice.setPrice(fullPrice);
productResponse.setPrice(fullPrice);
productResponse.setSalePrice(fullPrice + "-" + fullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END///////////////////////////////
}
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////
Set<ProductProp> propSet = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
// 颜色描述
productPropColor.setPropId(pId);
productPropColor.setPropName(pColor);
productPropColor.setImage(pImg);
propSet.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSet.addAll(oldPropSet);
productPropSet.put("颜色", propSet);
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.ZARA.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
}
package com.diaoyun.zion.master.util.spider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import java.math.BigDecimal;
import java.util.*;
/**
* MassimoDutti 爬虫数据解析
* @see com.diaoyun.zion.chinafrica.bis.impl.MassimoduttiSpider 数据爬虫
* @author 爱酱油不爱醋
*/
public class MassimoDuttiSpiderParse {
/**
* 格式化返回数据
* @param dataMap 主要的 json 数据
* @param pId 商品链接的 id
* @return 格式化后的数据
*/
public static ProductResponse formatProductResponse(JSONObject dataMap, String pId) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
// 商品基本信息
ItemInfo itemInfo = new ItemInfo();
//////////////////////////////////// 获取商品基本信息 ////////////////////////////////////////////
itemInfo.setShopName(PlatformEnum.MASSIMODUTTI.getLabel());
itemInfo.setShopUrl("https://www.massimodutti.cn/cn/");
itemInfo.setItemId(pId);
itemInfo.setTitle(dataMap.getString("name"));
//////////////////////////////////// 获取商品基本信息End(图片下取) ////////////////////////////////////////////
// 取 detail 节点对象
JSONObject detailObj = dataMap.getJSONObject("detail");
// 取 colors 节点数组
JSONArray colorsArr = detailObj.getJSONArray("colors");
for (int i = 0; i < colorsArr.size(); i++) {
JSONObject colorsObj = colorsArr.getJSONObject(i);
// 取 image 节点对象
JSONObject imageObj = colorsObj.getJSONObject("image");
// 处理商品链接
String imageUrl = "https://static.massimodutti.cn/3/photos"
+ imageObj.getString("url")
+ "_2_5_16.jpg?t="
+ imageObj.getString("timestamp");
if (i == 0) {
itemInfo.setPic(imageUrl);
}
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////////////////////
Set<ProductProp> propSetColor = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
// 颜色id
String colorNo = colorsObj.getString("id");
productPropColor.setPropId(colorNo);
// 颜色名
productPropColor.setPropName(colorsObj.getString("name"));
// 颜色图片
productPropColor.setImage(imageUrl);
if (i == 0) {
itemInfo.setPic(imageUrl);
}
propSetColor.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSetColor);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSetColor.addAll(oldPropSet);
productPropSet.put("颜色", propSetColor);
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
///////////////////////// 获取商品尺码属性 ////////////////////
// 取 sizes 节点对象
JSONArray sizesArr = colorsObj.getJSONArray("sizes");
for (int j = 0; j < sizesArr.size(); j++) {
JSONObject sizesObj = sizesArr.getJSONObject(j);
Set<ProductProp> sizePropSetSize = new HashSet<>(16);
ProductProp productPropSize = new ProductProp();
productPropSize.setPropName(sizesObj.getString("name"));
String sizeNo = sizesObj.getString("sku");
productPropSize.setPropId(sizeNo);
sizePropSetSize.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSetSize);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSetSize.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSetSize);
}
///////////////////////// 获取商品尺码属性 END////////////////////
// 库存 id
String skuStr = ";" + colorNo + ";" + sizeNo;
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,Uniqlo 未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
String fullPrice = sizesObj.getString("price");
BigDecimal priceOld = new BigDecimal(fullPrice);
BigDecimal div = new BigDecimal("100");
BigDecimal priceNew = priceOld.divide(div, 2, BigDecimal.ROUND_HALF_UP);
// TODO 转换汇率,目前商品单位是人民币
fullPrice = SpiderUtil.exchangeRate(priceNew.toString());
originalPrice.setPrice(fullPrice);
productResponse.setPrice(fullPrice);
productResponse.setSalePrice(fullPrice + "-" + fullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END//////////////////////////////////
}
}
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.MASSIMODUTTI.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
}
package com.diaoyun.zion.master.util.spider;
public class MocoSpiderParse {
}
package com.diaoyun.zion.master.util.spider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.util.*;
/**
* Ochirly 数据爬虫
* @see com.diaoyun.zion.chinafrica.bis.impl.OchirlySpider
* @author 爱酱油不爱醋
*/
public class OchirlySpiderParse {
/**
* 格式化返回数据
* @param content 主要的页面数据
* @return 格式化后的数据
*/
public static ProductResponse formatProductResponse(String content) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
Document document = Jsoup.parse(content);
// 获取标题
Elements detailEle = document.select("div[class=detail]").select("div[class=desc]");
String pTitle = detailEle.select("h5").text();
// 获取价格
Elements priceEle = detailEle.select("p[class=price]");
String fullPrice = priceEle.attr("data-list-price");
// 获取颜色id与图片
Elements colorEle = document.select("div[class=color]").select("ul[class=clearfix]");
List<String> imgUrlList = colorEle.select("a").eachAttr("href");
List<String> pColorNoList = new ArrayList<>();
for (int i = 0; i < imgUrlList.size(); i++) {
String hrefStr = imgUrlList.get(i);
if (hrefStr.contains("/p/mobile/")) {
String[] spilt = hrefStr.split("/mobile/");
pColorNoList.add(spilt[1].replaceAll(".shtml", ""));
} else {
pColorNoList.add(0, priceEle.attr("data-sku"));
}
}
List<String> pColorList = new ArrayList<>();
pColorList.addAll(pColorNoList);
List<String> pImgList = colorEle.select("img").eachAttr("src");
// 获取尺码
Elements sizeEle = document.select("div[class=size]").select("div[class=size_contain]").select("li");
List<String> pSizeList = sizeEle.eachText();
List<String> pSizeNoList = sizeEle.eachAttr("data-size-id");
//////////////////////////////////// 获取商品基本信息 ////////////////////////////
ItemInfo itemInfo = new ItemInfo();
itemInfo.setShopName(PlatformEnum.OCHIRLY.getLabel());
itemInfo.setShopUrl("www.ochirly.com");
itemInfo.setItemId(detailEle.select("p[class=price]").attr("data-sku"));
itemInfo.setTitle(pTitle);
itemInfo.setPic(pImgList.get(0));
//////////////////////////////////// 获取商品基本信息End /////////////////////////
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////
for (int i = 0; i < pColorList.size(); i++) {
Set<ProductProp> propSet = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
productPropColor.setPropName(pColorList.get(i));
productPropColor.setPropId(pColorNoList.get(i));
productPropColor.setImage(pImgList.get(i));
propSet.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSet.addAll(oldPropSet);
productPropSet.put("颜色", propSet);
}
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
///////////////////////// 获取商品尺码属性 ////////////////////
for (int i = 0; i < pSizeList.size(); i++) {
Set<ProductProp> sizePropSet = new HashSet<>();
ProductProp productPropSize = new ProductProp();
productPropSize.setPropId(pSizeNoList.get(i));
productPropSize.setPropName(pSizeList.get(i));
sizePropSet.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSet.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSet);
}
}
///////////////////////// 获取商品尺码属性 END////////////////////
//////////////////////////////////// 获取库存与原始价 ////////////////////////////////////////////
for (String pColorNo : pColorNoList) {
for (String pSizeNo : pSizeNoList) {
// 设置库存id
String skuStr = ";" + pColorNo + ";" + pSizeNo + ";";
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
ProductSkuStock productSkuStock = new ProductSkuStock();
OriginalPrice originalPrice = new OriginalPrice();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
// 设置:可用库存值,未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
// TODO 转换汇率,目前商品单位是人民币
String originalFullPrice = SpiderUtil.exchangeRate(fullPrice);
originalPrice.setPrice(originalFullPrice);
productResponse.setPrice(originalFullPrice);
productResponse.setSalePrice(originalFullPrice + "-" + originalFullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
}
}
//////////////////////////////////// 获取库存与原始价 END///////////////////////////////
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.OCHIRLY.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
}
package com.diaoyun.zion.master.util.spider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import java.math.BigDecimal;
import java.util.*;
/**
* PullAndBear 爬虫数据解析
* @see com.diaoyun.zion.chinafrica.bis.impl.PullandbearSpider 数据爬虫
* @author 爱酱油不爱醋
*/
public class PullAndBearSpiderParse {
/**
* 格式化 PullAndBear 返回数据
* @param dataMap 主要的 json 数据
* @param pId 商品链接的 id
* @return 格式化后的数据
*/
public static ProductResponse formatProductResponse(JSONObject dataMap, String pId) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
// 商品基本信息
ItemInfo itemInfo = new ItemInfo();
// 取 bundleProductSummaries 的节点对象
JSONObject bundleProductSummariesObj = dataMap.getJSONArray("bundleProductSummaries").getJSONObject(0);
//////////////////////////////////// 获取商品基本信息 ////////////////////////////////////////////
itemInfo.setShopName(PlatformEnum.PULLANDBEAR.getLabel());
itemInfo.setShopUrl("https://www.pullandbear.cn/cn/");
itemInfo.setItemId(pId);
itemInfo.setTitle(bundleProductSummariesObj.getString("name"));
//////////////////////////////////// 获取商品基本信息End(图片下取) ////////////////////////////////////////////
// 取 colors 数组节点
JSONArray colorsArr = bundleProductSummariesObj.getJSONObject("detail").getJSONArray("colors");
for (int i = 0; i < colorsArr.size(); i++) {
JSONObject colorsObj = colorsArr.getJSONObject(i);
//////////////////////////////////// 获取商品颜色与图片属性 ////////////////////////////////////////////
Set<ProductProp> propSetColor = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
// 颜色id
String colorNo = colorsObj.getString("id");
productPropColor.setPropId(colorNo);
// 颜色名
String colorName = colorsObj.getString("name");
productPropColor.setPropName(colorName);
// 取 image 对象节点
JSONObject imageObj = colorsObj.getJSONObject("image");
// 颜色图片
String imageUrl = "https://static.pullandbear.cn/2/photos/"
+ imageObj.getString("url")
+ "_2_1_8.jpg?t="
+ imageObj.getString("timestamp");
productPropColor.setImage(imageUrl);
if (i == 0) {
itemInfo.setPic(imageUrl);
}
propSetColor.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSetColor);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSetColor.addAll(oldPropSet);
productPropSet.put("颜色", propSetColor);
}
//////////////////////////////////// 获取商品颜色与图片属性 END ////////////////////////////////////////////
// 取 siezes 对象数组
JSONArray sizesArr = colorsObj.getJSONArray("sizes");
for (int j = 0; j < sizesArr.size(); j++) {
JSONObject sizesObj = sizesArr.getJSONObject(j);
///////////////////////// 获取商品尺码属性 ////////////////////
Set<ProductProp> sizePropSetSize = new HashSet<>();
ProductProp productPropSize = new ProductProp();
String size = sizesObj.getString("name");
productPropSize.setPropName(size);
String sizeNo = sizesObj.getString("sku");
productPropSize.setPropId(sizeNo);
sizePropSetSize.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSetSize);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSetSize.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSetSize);
}
///////////////////////// 获取商品尺码属性 END////////////////////
// 商品的库存id
String skuStr = ";" + colorNo + ";" + sizeNo + ";";
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,PullAndBear 未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
String fullPrice = sizesObj.getString("price");
BigDecimal priceOld=new BigDecimal(fullPrice);
BigDecimal div = new BigDecimal("100");
BigDecimal priceNew = priceOld.divide(div, 2, BigDecimal.ROUND_DOWN);
// TODO 转换汇率,目前商品单位是人民币
fullPrice= SpiderUtil.exchangeRate(priceNew.toString());
originalPrice.setPrice(fullPrice);
productResponse.setPrice(fullPrice);
productResponse.setSalePrice(fullPrice + "-" + fullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END//////////////////////////////////
}
}
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.PULLANDBEAR.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
}
package com.diaoyun.zion.master.util;
package com.diaoyun.zion.master.util.spider;
import com.diaoyun.zion.chinafrica.constant.KeyConstant;
import com.diaoyun.zion.chinafrica.entity.TbCfFeeEntity;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.service.TbCfFeeService;
import com.diaoyun.zion.chinafrica.vo.*;
import com.diaoyun.zion.master.util.SpringContextUtil;
import com.stripe.model.Product;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
......@@ -22,6 +23,19 @@ public class SpiderUtil {
rate = tbCfFeeService.getRateFee().getFeeRate();
}
/**
* 转换汇率
* @param fullPrice
* @return
*/
protected static String exchangeRate(String fullPrice) {
/* 获取人民币汇率 1美元换取人民币
* TODO 同步汇率问题
* 暂时从后台获取人工设置的汇率
*/
return new BigDecimal(fullPrice).divide(rate, 2, BigDecimal.ROUND_UP).toString();
}
/**
* 格式化 gap 返回数据
*
......@@ -292,20 +306,6 @@ public class SpiderUtil {
return productResponse;
}
/**
* 转换汇率
* @param fullPrice
* @return
*/
private static String exchangeRate(String fullPrice) {
/* 获取人民币汇率 1美元换取人民币
* TODO 同步汇率问题
* 暂时从后台获取人工设置的汇率
*/
return new BigDecimal(fullPrice).divide(rate, 2, BigDecimal.ROUND_UP).toString();
}
/**
* 格式化 afric-eshop 返回数据
*
......@@ -406,571 +406,6 @@ public class SpiderUtil {
return productResponse;
}
/**
* 格式化 Zara 返回数据
* @see com.diaoyun.zion.chinafrica.bis.impl.ZaraSpider
* @param dataMap
* @return
*/
public static ProductResponse formatZaraProductResponse(JSONObject dataMap) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
//////////////////////////////////// 获取商品基本信息 ////////////////////////////////////////////
ItemInfo itemInfo = new ItemInfo();
itemInfo.setShopName("Zara");
itemInfo.setShopUrl(dataMap.getString("backUrl"));
JSONObject productObj = dataMap.getJSONObject("product");
itemInfo.setItemId(productObj.getString("id"));
itemInfo.setTitle(productObj.getString("name"));
//////////////////////////////////// 获取商品基本信息End(图片下取) ////////////////////////////////////////////
// 取 colors 节点数组
JSONArray colorsArr = productObj.getJSONObject("detail").getJSONArray("colors");
for (int i = 0; i < colorsArr.size(); i++) {
JSONObject colorsObj = colorsArr.getJSONObject(i);
// 取 detailImagesArr 节点数组第一个对象
JSONObject detailImagesObj_0 = colorsObj.getJSONArray("detailImages").getJSONObject(0);
// 处理图片 参考路径:http://static.zara.cn/photos///2019/I/0/1/p/0858/457/800/17/w/1920/0858457800_1_1_1.jpg?ts=1570720340221
String imageUrl = "http://static.zara.cn/photos//"
+ detailImagesObj_0.getString("path")
+ "w/1920/"
+ detailImagesObj_0.getString("name")
+ "_1.jpg?ts="
+ detailImagesObj_0.getString("timestamp");
if (i == 0) {
// 商品基本信息--设置:图片
itemInfo.setPic(imageUrl);
}
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////////////////////
Set<ProductProp> propSet = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
// 颜色描述
productPropColor.setPropId(colorsObj.getString("productId"));
productPropColor.setPropName(colorsObj.getString("name"));
productPropColor.setImage(imageUrl);
propSet.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSet.addAll(oldPropSet);
productPropSet.put("颜色", propSet);
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
// 取 sizes 节点数组
JSONArray sizesArr = colorsArr.getJSONObject(i).getJSONArray("sizes");
for (int j = 0; j < sizesArr.size(); j++) {
JSONObject sizesObj = sizesArr.getJSONObject(j);
// 库存对应的id(Zara 中以颜色id + 尺码id)
String skuStr = ";" + colorsObj.getString("productId") + ";" + sizesObj.getString("sku") + ";";
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,Zara 未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
String fullPrice = sizesObj.getString("price");
BigDecimal priceOld=new BigDecimal(fullPrice);
BigDecimal div = new BigDecimal("100");
BigDecimal priceNew = priceOld.divide(div, 2, BigDecimal.ROUND_DOWN);
// TODO 转换汇率,目前商品单位是人民币
fullPrice= exchangeRate(priceNew.toString());
originalPrice.setPrice(fullPrice);
productResponse.setPrice(fullPrice);
productResponse.setSalePrice(fullPrice + "-" + fullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END//////////////////////////////////
///////////////////////// 获取商品尺码属性 ////////////////////
Set<ProductProp> sizePropSet = new HashSet<>();
ProductProp productPropSize = new ProductProp();
String size = sizesObj.getString("name");
productPropSize.setPropId(sizesObj.getString("sku"));
productPropSize.setPropName(size);
sizePropSet.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSet.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSet);
}
///////////////////////// 获取商品尺码属性 END////////////////////
}
}
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.ZARA.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
/**
* 格式化 Uniqlo优衣库 返回数据
* @see com.diaoyun.zion.chinafrica.bis.impl.UniqloSpider
* @param dataMap 调用优衣库网页接口接收的主要商品数据
* @param pId 商品链接截取的商品id
* @return
*/
public static ProductResponse formatUniqloProductResponse(JSONObject dataMap, JSONObject priceJson, String pId) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
// 商品基本信息
ItemInfo itemInfo = new ItemInfo();
// 取 summary 节点对象
JSONObject summaryObj = dataMap.getJSONObject("summary");
//////////////////////////////////// 获取商品基本信息 ////////////////////////////////////////////
itemInfo.setShopName(PlatformEnum.UNIQLO.getLabel());
itemInfo.setShopUrl("https://www.uniqlo.cn/product-detail.html");
itemInfo.setItemId(pId);
itemInfo.setTitle(summaryObj.getString("fullName"));
//////////////////////////////////// 获取商品基本信息End(图片下取) ////////////////////////////////////////////
// 取 rows 节点数组
JSONArray rowsArr = dataMap.getJSONArray("rows");
for (int i = 0; i < rowsArr.size(); i++) {
JSONObject rowsObj = rowsArr.getJSONObject(i);
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////////////////////
Set<ProductProp> propSetColor = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
// 颜色id
String colorNo = rowsObj.getString("colorNo");
productPropColor.setPropId(colorNo);
// 颜色名
String colorName = rowsObj.getString("style");
productPropColor.setPropName(colorName);
// 颜色图片
String imageUrl = "https://www.uniqlo.cn/hmall/test/" + pId + "/sku/561/" + colorNo + ".jpg";
productPropColor.setImage(imageUrl);
if (i == 0) {
itemInfo.setPic(imageUrl);
}
propSetColor.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSetColor);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSetColor.addAll(oldPropSet);
productPropSet.put("颜色", propSetColor);
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
///////////////////////// 获取商品尺码属性 ////////////////////
Set<ProductProp> sizePropSetSize = new HashSet<>();
ProductProp productPropSize = new ProductProp();
String size = rowsObj.getString("sizeText");
productPropSize.setPropName(size);
String sizeNo = rowsObj.getString("skuId");
productPropSize.setPropId(sizeNo);
sizePropSetSize.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSetSize);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSetSize.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSetSize);
}
///////////////////////// 获取商品尺码属性 END////////////////////
String skuStr = ";" + colorNo + ";" + sizeNo + ";";
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,Uniqlo 未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
String fullPrice = summaryObj.getString("originPrice");
// TODO 转换汇率,目前商品单位是人民币
fullPrice = exchangeRate(fullPrice);
originalPrice.setPrice(fullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END//////////////////////////////////
//////////////////////////////////// 获取促销价 //////////////////////////////////
// 取 summary 节点对象
JSONObject summaryPriceObj = priceJson.getJSONArray("resp").getJSONObject(0).getJSONObject("summary");
ProductPromotion productPromotion = new ProductPromotion();
// 获取商品的促销价
String promotionPrice = summaryPriceObj.getString("maxPrice");
// TODO 转换汇率,目前商品单位是人民币
promotionPrice = exchangeRate(promotionPrice);
productPromotion.setSkuStr(skuStr);
productPromotion.setPrice(promotionPrice);
productResponse.setPrice(promotionPrice);
productResponse.setSalePrice(promotionPrice + "-" + fullPrice);
promotionList.add(productPromotion);
//////////////////////////////////// 获取促销价 END//////////////////////////////////
}
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setPromotionFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.UNIQLO.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
/**
* 格式化 MassimoDutti 返回数据
* @see com.diaoyun.zion.chinafrica.bis.impl.MassimoduttiSpider
* @param dataMap 主要的 json 数据
* @param pId 商品链接的 id
* @return 格式化后的数据
*/
public static ProductResponse formatMassimoDuttiProductResponse(JSONObject dataMap, String pId) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
// 商品基本信息
ItemInfo itemInfo = new ItemInfo();
//////////////////////////////////// 获取商品基本信息 ////////////////////////////////////////////
itemInfo.setShopName(PlatformEnum.MASSIMODUTTI.getLabel());
itemInfo.setShopUrl("https://www.massimodutti.cn/cn/");
itemInfo.setItemId(pId);
itemInfo.setTitle(dataMap.getString("name"));
//////////////////////////////////// 获取商品基本信息End(图片下取) ////////////////////////////////////////////
// 取 detail 节点对象
JSONObject detailObj = dataMap.getJSONObject("detail");
// 取 colors 节点数组
JSONArray colorsArr = detailObj.getJSONArray("colors");
for (int i = 0; i < colorsArr.size(); i++) {
JSONObject colorsObj = colorsArr.getJSONObject(i);
// 取 image 节点对象
JSONObject imageObj = colorsObj.getJSONObject("image");
// 处理商品链接
String imageUrl = "https://static.massimodutti.cn/3/photos"
+ imageObj.getString("url")
+ "_2_5_16.jpg?t="
+ imageObj.getString("timestamp");
if (i == 0) {
itemInfo.setPic(imageUrl);
}
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////////////////////
Set<ProductProp> propSetColor = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
// 颜色id
String colorNo = colorsObj.getString("id");
productPropColor.setPropId(colorNo);
// 颜色名
productPropColor.setPropName(colorsObj.getString("name"));
// 颜色图片
productPropColor.setImage(imageUrl);
if (i == 0) {
itemInfo.setPic(imageUrl);
}
propSetColor.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSetColor);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSetColor.addAll(oldPropSet);
productPropSet.put("颜色", propSetColor);
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
///////////////////////// 获取商品尺码属性 ////////////////////
// 取 sizes 节点对象
JSONArray sizesArr = colorsObj.getJSONArray("sizes");
for (int j = 0; j < sizesArr.size(); j++) {
JSONObject sizesObj = sizesArr.getJSONObject(j);
Set<ProductProp> sizePropSetSize = new HashSet<>(16);
ProductProp productPropSize = new ProductProp();
productPropSize.setPropName(sizesObj.getString("name"));
String sizeNo = sizesObj.getString("sku");
productPropSize.setPropId(sizeNo);
sizePropSetSize.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSetSize);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSetSize.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSetSize);
}
///////////////////////// 获取商品尺码属性 END////////////////////
// 库存 id
String skuStr = ";" + colorNo + ";" + sizeNo;
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,Uniqlo 未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
String fullPrice = sizesObj.getString("price");
BigDecimal priceOld = new BigDecimal(fullPrice);
BigDecimal div = new BigDecimal("100");
BigDecimal priceNew = priceOld.divide(div, 2, BigDecimal.ROUND_HALF_UP);
// TODO 转换汇率,目前商品单位是人民币
fullPrice = exchangeRate(priceNew.toString());
originalPrice.setPrice(fullPrice);
productResponse.setPrice(fullPrice);
productResponse.setSalePrice(fullPrice + "-" + fullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END//////////////////////////////////
}
}
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.MASSIMODUTTI.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
/**
* 格式化 PullAndBear 返回数据
* @see com.diaoyun.zion.chinafrica.bis.impl.PullandbearSpider
* @param dataMap 主要的 json 数据
* @param pId 商品链接的 id
* @return 格式化后的数据
*/
public static ProductResponse formatPullAndBearProductResponse(JSONObject dataMap, String pId) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
// 商品基本信息
ItemInfo itemInfo = new ItemInfo();
// 取 bundleProductSummaries 的节点对象
JSONObject bundleProductSummariesObj = dataMap.getJSONArray("bundleProductSummaries").getJSONObject(0);
//////////////////////////////////// 获取商品基本信息 ////////////////////////////////////////////
itemInfo.setShopName(PlatformEnum.PULLANDBEAR.getLabel());
itemInfo.setShopUrl("https://www.pullandbear.cn/cn/");
itemInfo.setItemId(pId);
itemInfo.setTitle(bundleProductSummariesObj.getString("name"));
//////////////////////////////////// 获取商品基本信息End(图片下取) ////////////////////////////////////////////
// 取 colors 数组节点
JSONArray colorsArr = bundleProductSummariesObj.getJSONObject("detail").getJSONArray("colors");
for (int i = 0; i < colorsArr.size(); i++) {
JSONObject colorsObj = colorsArr.getJSONObject(i);
//////////////////////////////////// 获取商品颜色与图片属性 ////////////////////////////////////////////
Set<ProductProp> propSetColor = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
// 颜色id
String colorNo = colorsObj.getString("id");
productPropColor.setPropId(colorNo);
// 颜色名
String colorName = colorsObj.getString("name");
productPropColor.setPropName(colorName);
// 取 image 对象节点
JSONObject imageObj = colorsObj.getJSONObject("image");
// 颜色图片
String imageUrl = "https://static.pullandbear.cn/2/photos/"
+ imageObj.getString("url")
+ "_2_1_8.jpg?t="
+ imageObj.getString("timestamp");
productPropColor.setImage(imageUrl);
if (i == 0) {
itemInfo.setPic(imageUrl);
}
propSetColor.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSetColor);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSetColor.addAll(oldPropSet);
productPropSet.put("颜色", propSetColor);
}
//////////////////////////////////// 获取商品颜色与图片属性 END ////////////////////////////////////////////
// 取 siezes 对象数组
JSONArray sizesArr = colorsObj.getJSONArray("sizes");
for (int j = 0; j < sizesArr.size(); j++) {
JSONObject sizesObj = sizesArr.getJSONObject(j);
///////////////////////// 获取商品尺码属性 ////////////////////
Set<ProductProp> sizePropSetSize = new HashSet<>();
ProductProp productPropSize = new ProductProp();
String size = sizesObj.getString("name");
productPropSize.setPropName(size);
String sizeNo = sizesObj.getString("sku");
productPropSize.setPropId(sizeNo);
sizePropSetSize.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSetSize);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSetSize.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSetSize);
}
///////////////////////// 获取商品尺码属性 END////////////////////
// 商品的库存id
String skuStr = ";" + colorNo + ";" + sizeNo + ";";
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,PullAndBear 未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
String fullPrice = sizesObj.getString("price");
BigDecimal priceOld=new BigDecimal(fullPrice);
BigDecimal div = new BigDecimal("100");
BigDecimal priceNew = priceOld.divide(div, 2, BigDecimal.ROUND_DOWN);
// TODO 转换汇率,目前商品单位是人民币
fullPrice= exchangeRate(priceNew.toString());
originalPrice.setPrice(fullPrice);
productResponse.setPrice(fullPrice);
productResponse.setSalePrice(fullPrice + "-" + fullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END//////////////////////////////////
}
}
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.PULLANDBEAR.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
/**
* 格式化 H&M 返回数据
* @see com.diaoyun.zion.chinafrica.bis.impl.HmSpider
......
package com.diaoyun.zion.master.util.spider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.util.*;
/**
* UnderArmour 爬虫数据解析
* @see com.diaoyun.zion.chinafrica.bis.impl.UnderArmourSpider
* @author 爱酱油不爱醋
*/
public class UnderArmourSpiderParse {
/**
* 格式化返回数据
* @param content 主要的页面数据
* @return 格式化后的数据
*/
public static ProductResponse formatProductResponse(String content) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
// 解析成 Document 对象
Document document = Jsoup.parse(content);
// 获取商品的标题、价格、颜色名称及id、尺码名称及id
String pId = document.select("span[class=e-color-show]").text();
String pTitle = document.select("h3[class=commo-name]").text();
String fullPrice = document.select("p[class=commo-price]").text().replaceAll("¥", "");
Elements colorEle = document.select("ul[class=color-choice float-clearfix e-color-choice]").select("li");
List<String> pColorList = colorEle.eachText();
List<String> pColorNoList = colorEle.eachAttr("itemcode");
Elements sizeEle = document.select("ul[class=size-choice float-clearfix e-size-choice]").select("li");
List<String> pSizeList = sizeEle.eachText();
List<String> pSizeNoList = sizeEle.eachAttr("skuid");
//////////////////////////////////// 获取商品基本信息 ////////////////////////////
ItemInfo itemInfo = new ItemInfo();
itemInfo.setShopName(PlatformEnum.UNDERARMOUR.getLabel());
itemInfo.setShopUrl("https://www.adidas.com");
itemInfo.setItemId(pId);
itemInfo.setTitle(pTitle);
itemInfo.setPic("https://underarmour.scene7.com/is/image/Underarmour/V5-" + pId + "_FC_Main");
//////////////////////////////////// 获取商品基本信息End /////////////////////////
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////
for (int i = 0; i < pColorList.size(); i++) {
Set<ProductProp> propSet = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
productPropColor.setPropName(pColorList.get(i));
productPropColor.setPropId(pColorNoList.get(i));
productPropColor.setImage("https://underarmour.scene7.com/is/image/Underarmour/V5-" + pColorNoList.get(i) + "_FC_Main");
propSet.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSet.addAll(oldPropSet);
productPropSet.put("颜色", propSet);
}
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
///////////////////////// 获取商品尺码属性 ////////////////////
for (int i = 0; i < pSizeList.size(); i++) {
Set<ProductProp> sizePropSet = new HashSet<>();
ProductProp productPropSize = new ProductProp();
productPropSize.setPropId(pSizeNoList.get(i));
productPropSize.setPropName(pSizeList.get(i));
sizePropSet.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSet.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSet);
}
}
///////////////////////// 获取商品尺码属性 END////////////////////
//////////////////////////////////// 获取库存与原始价 ////////////////////////////////////////////
for (String pColorNo : pColorNoList) {
for (String pSizeNo : pSizeNoList) {
// 设置库存id
String skuStr = ";" + pColorNo + ";" + pSizeNo + ";";
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
ProductSkuStock productSkuStock = new ProductSkuStock();
OriginalPrice originalPrice = new OriginalPrice();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
// 设置:可用库存值,未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
// TODO 转换汇率,目前商品单位是人民币
String originalFullPrice = SpiderUtil.exchangeRate(fullPrice);
originalPrice.setPrice(originalFullPrice);
productResponse.setPrice(originalFullPrice);
productResponse.setSalePrice(originalFullPrice + "-" + originalFullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
}
}
//////////////////////////////////// 获取库存与原始价 END///////////////////////////////
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.UNDERARMOUR.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
}
package com.diaoyun.zion.master.util.spider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import java.util.*;
/**
* Uniqlo 数据爬虫
* @see com.diaoyun.zion.chinafrica.bis.impl.UniqloSpider
* @author 爱酱油不爱醋
*/
public class UniqloSpiderParse {
/**
* 返回格式化数据
* @param dataMap 调用优衣库网页接口接收的主要商品数据
* @param pId 商品链接截取的商品id
* @return
*/
public static ProductResponse formatProductResponse(JSONObject dataMap, JSONObject priceJson, String pId) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
// 商品基本信息
ItemInfo itemInfo = new ItemInfo();
// 取 summary 节点对象
JSONObject summaryObj = dataMap.getJSONObject("summary");
//////////////////////////////////// 获取商品基本信息 ////////////////////////////////////////////
itemInfo.setShopName(PlatformEnum.UNIQLO.getLabel());
itemInfo.setShopUrl("https://www.uniqlo.cn/product-detail.html");
itemInfo.setItemId(pId);
itemInfo.setTitle(summaryObj.getString("fullName"));
//////////////////////////////////// 获取商品基本信息End(图片下取) ////////////////////////////////////////////
// 取 rows 节点数组
JSONArray rowsArr = dataMap.getJSONArray("rows");
for (int i = 0; i < rowsArr.size(); i++) {
JSONObject rowsObj = rowsArr.getJSONObject(i);
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////////////////////
Set<ProductProp> propSetColor = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
// 颜色id
String colorNo = rowsObj.getString("colorNo");
productPropColor.setPropId(colorNo);
// 颜色名
String colorName = rowsObj.getString("style");
productPropColor.setPropName(colorName);
// 颜色图片
String imageUrl = "https://www.uniqlo.cn/hmall/test/" + pId + "/sku/561/" + colorNo + ".jpg";
productPropColor.setImage(imageUrl);
if (i == 0) {
itemInfo.setPic(imageUrl);
}
propSetColor.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSetColor);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSetColor.addAll(oldPropSet);
productPropSet.put("颜色", propSetColor);
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
///////////////////////// 获取商品尺码属性 ////////////////////
Set<ProductProp> sizePropSetSize = new HashSet<>();
ProductProp productPropSize = new ProductProp();
String size = rowsObj.getString("sizeText");
productPropSize.setPropName(size);
String sizeNo = rowsObj.getString("skuId");
productPropSize.setPropId(sizeNo);
sizePropSetSize.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSetSize);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSetSize.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSetSize);
}
///////////////////////// 获取商品尺码属性 END////////////////////
String skuStr = ";" + colorNo + ";" + sizeNo + ";";
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,Uniqlo 未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
String fullPrice = summaryObj.getString("originPrice");
// TODO 转换汇率,目前商品单位是人民币
fullPrice = SpiderUtil.exchangeRate(fullPrice);
originalPrice.setPrice(fullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END//////////////////////////////////
//////////////////////////////////// 获取促销价 //////////////////////////////////
// 取 summary 节点对象
JSONObject summaryPriceObj = priceJson.getJSONArray("resp").getJSONObject(0).getJSONObject("summary");
ProductPromotion productPromotion = new ProductPromotion();
// 获取商品的促销价
String promotionPrice = summaryPriceObj.getString("maxPrice");
// TODO 转换汇率,目前商品单位是人民币
promotionPrice = SpiderUtil.exchangeRate(promotionPrice);
productPromotion.setSkuStr(skuStr);
productPromotion.setPrice(promotionPrice);
productResponse.setPrice(promotionPrice);
productResponse.setSalePrice(promotionPrice + "-" + fullPrice);
promotionList.add(productPromotion);
//////////////////////////////////// 获取促销价 END//////////////////////////////////
}
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setPromotionFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.UNIQLO.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
}
package com.diaoyun.zion.master.util.spider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import java.util.*;
import static com.diaoyun.zion.master.util.spider.SpiderUtil.exchangeRate;
/**
* UrbanRevivo 爬虫数据解析
* @see com.diaoyun.zion.chinafrica.bis.impl.UrbanRevivoSpider
* @author 爱酱油不爱醋
*/
public class UrbanRevivoSpiderParse {
/**
* 格式化返回数据
* @param dataMap 主要的 json 数据
* @param pId 截取的商品 id
* @return 格式化后的数据
*/
public static ProductResponse formatProductResponse(JSONObject dataMap, String pId) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
// 取 data 数据节点
JSONObject dataObj = dataMap.getJSONObject("data");
//////////////////////////////////// 获取商品基本信息 ////////////////////////////////////////////
ItemInfo itemInfo = new ItemInfo();
itemInfo.setShopName(PlatformEnum.URBANREVIVO.getLabel());
itemInfo.setShopUrl("http://www.ur.cn/index.html");
itemInfo.setItemId(pId);
itemInfo.setTitle(dataObj.getString("name"));
itemInfo.setPic("https://gw-img.ur.com.cn//" + dataObj.getString("image"));
//////////////////////////////////// 获取商品基本信息End////////////////////////////////////////////
// 取 colors 节点数组
JSONArray colorsArr = dataObj.getJSONArray("colors");
for (int i = 0; i < colorsArr.size(); i++) {
JSONObject colorsObj = colorsArr.getJSONObject(i);
// 获取图片路径
String imgUrl = "https://gw-img.ur.com.cn//" + colorsObj.getString("image");
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////////////////////
Set<ProductProp> propSet = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
String colorNo = colorsObj.getString("productColorId");
productPropColor.setPropId(colorNo);
productPropColor.setPropName(colorsObj.getString("aliasName"));
productPropColor.setImage(imgUrl);
propSet.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSet.addAll(oldPropSet);
productPropSet.put("颜色", propSet);
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
// 取 skus 节点数组
JSONArray skusArr = colorsObj.getJSONArray("skus");
for (int j = 0; j < skusArr.size(); j++) {
JSONObject skusObj = skusArr.getJSONObject(j);
///////////////////////// 获取商品尺码属性 ////////////////////
Set<ProductProp> sizePropSet = new HashSet<>();
ProductProp productPropSize = new ProductProp();
String sizeNo = skusObj.getString("barCode");
productPropSize.setPropId(sizeNo);
productPropSize.setPropName(skusObj.getString("sizeAlias"));
sizePropSet.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSet.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSet);
}
///////////////////////// 获取商品尺码属性 END////////////////////
// 设置库存id
String skuStr = ";" + colorNo + ";" + sizeNo + ";";
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
String fullPrice = dataObj.getString("tagPrice");
// TODO 转换汇率,目前商品单位是人民币
fullPrice = exchangeRate(fullPrice);
originalPrice.setPrice(fullPrice);
productResponse.setPrice(fullPrice);
productResponse.setSalePrice(fullPrice + "-" + fullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END//////////////////////////////////
}
}
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.URBANREVIVO.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
}
package com.diaoyun.zion.master.util.spider;
import com.diaoyun.zion.chinafrica.enums.PlatformEnum;
import com.diaoyun.zion.chinafrica.vo.*;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import java.math.BigDecimal;
import java.util.*;
import static com.diaoyun.zion.master.util.spider.SpiderUtil.exchangeRate;
/**
* Zara 爬虫数据解析
* @see com.diaoyun.zion.chinafrica.bis.impl.ZaraSpider
* @author 爱酱油不爱醋
*/
public class ZaraSpiderParse {
/**
* 获取主要数据
* @param content 商品的 HTML 页面
* @return 截取后的主要数据
*/
public static JSONObject getJsonData(String content) {
int labelHeadIndex = content.indexOf("dataLayer");
int labelTailIndex = content.lastIndexOf(";window.zara.viewPayload");
String abv = content.substring(labelHeadIndex, labelTailIndex).replace("dataLayer = ", "");
JSONObject dataMap= JSONObject.fromObject(abv);
return dataMap;
}
/**
* 格式化返回数据
* @param dataMap 主要的 json 数据
* @return 格式化后的数据
*/
public static ProductResponse formatProductResponse(JSONObject dataMap) {
// 声明封装类
ProductResponse productResponse = new ProductResponse();
// 属性:Zara 的商品属性有颜色、尺码
Map<String, Set<ProductProp>> productPropSet = new HashMap<>(16);
// 原始价
List<OriginalPrice> originalPriceList = new ArrayList<>();
// 促销价格
List<ProductPromotion> promotionList = new ArrayList<>();
// 库存
DynStock dynStock = new DynStock();
// 其实数据没有包含确切的库存数,这里默认给足量的库存
dynStock.setSellableQuantity(9999);
//////////////////////////////////// 获取商品基本信息 ////////////////////////////////////////////
ItemInfo itemInfo = new ItemInfo();
itemInfo.setShopName("Zara");
itemInfo.setShopUrl(dataMap.getString("backUrl"));
JSONObject productObj = dataMap.getJSONObject("product");
itemInfo.setItemId(productObj.getString("id"));
itemInfo.setTitle(productObj.getString("name"));
//////////////////////////////////// 获取商品基本信息End(图片下取) ////////////////////////////////////////////
// 取 colors 节点数组
JSONArray colorsArr = productObj.getJSONObject("detail").getJSONArray("colors");
for (int i = 0; i < colorsArr.size(); i++) {
JSONObject colorsObj = colorsArr.getJSONObject(i);
// 取 detailImagesArr 节点数组第一个对象
JSONObject detailImagesObj_0 = colorsObj.getJSONArray("detailImages").getJSONObject(0);
// 处理图片 参考路径:http://static.zara.cn/photos///2019/I/0/1/p/0858/457/800/17/w/1920/0858457800_1_1_1.jpg?ts=1570720340221
String imageUrl = "http://static.zara.cn/photos//"
+ detailImagesObj_0.getString("path")
+ "w/1920/"
+ detailImagesObj_0.getString("name")
+ "_1.jpg?ts="
+ detailImagesObj_0.getString("timestamp");
if (i == 0) {
// 商品基本信息--设置:图片
itemInfo.setPic(imageUrl);
}
//////////////////////////////////// 获取商品颜色属性 ////////////////////////////////////////////
Set<ProductProp> propSet = new HashSet<>(16);
ProductProp productPropColor = new ProductProp();
// 颜色描述
productPropColor.setPropId(colorsObj.getString("productId"));
productPropColor.setPropName(colorsObj.getString("name"));
productPropColor.setImage(imageUrl);
propSet.add(productPropColor);
if (productPropSet.get("颜色") == null) {
productPropSet.put("颜色", propSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("颜色");
propSet.addAll(oldPropSet);
productPropSet.put("颜色", propSet);
}
//////////////////////////////////// 获取商品颜色属性 END ////////////////////////////////////////////
// 取 sizes 节点数组
JSONArray sizesArr = colorsArr.getJSONObject(i).getJSONArray("sizes");
for (int j = 0; j < sizesArr.size(); j++) {
JSONObject sizesObj = sizesArr.getJSONObject(j);
// 库存对应的id(Zara 中以颜色id + 尺码id)
String skuStr = ";" + colorsObj.getString("productId") + ";" + sizesObj.getString("sku") + ";";
//////////////////////////////////// 获取库存 ////////////////////////////////////////////
// 设置:商品包含库存信息
productResponse.setStockFlag(true);
List<ProductSkuStock> productSkuStockList = dynStock.getProductSkuStockList();
if (productSkuStockList == null) {
productSkuStockList = new ArrayList<>();
}
ProductSkuStock productSkuStock = new ProductSkuStock();
// 设置:可用库存值,Zara 未有可用的库存数据
productSkuStock.setSellableQuantity(999);
// 设置:库存对应的id
productSkuStock.setSkuStr(skuStr);
productSkuStockList.add(productSkuStock);
dynStock.setProductSkuStockList(productSkuStockList);
//////////////////////////////////// 获取库存 END/////////////////////////////////////////
//////////////////////////////////// 获取原始价 //////////////////////////////////
OriginalPrice originalPrice = new OriginalPrice();
// 获取商品的原始价
String fullPrice = sizesObj.getString("price");
BigDecimal priceOld=new BigDecimal(fullPrice);
BigDecimal div = new BigDecimal("100");
BigDecimal priceNew = priceOld.divide(div, 2, BigDecimal.ROUND_DOWN);
// TODO 转换汇率,目前商品单位是人民币
fullPrice = exchangeRate(priceNew.toString());
originalPrice.setPrice(fullPrice);
productResponse.setPrice(fullPrice);
productResponse.setSalePrice(fullPrice + "-" + fullPrice);
originalPrice.setSkuStr(skuStr);
originalPriceList.add(originalPrice);
//////////////////////////////////// 获取原始价 END//////////////////////////////////
///////////////////////// 获取商品尺码属性 ////////////////////
Set<ProductProp> sizePropSet = new HashSet<>();
ProductProp productPropSize = new ProductProp();
String size = sizesObj.getString("name");
productPropSize.setPropId(sizesObj.getString("sku"));
productPropSize.setPropName(size);
sizePropSet.add(productPropSize);
if (productPropSet.get("尺码") == null) {
productPropSet.put("尺码", sizePropSet);
} else {
Set<ProductProp> oldPropSet = productPropSet.get("尺码");
sizePropSet.addAll(oldPropSet);
productPropSet.put("尺码", sizePropSet);
}
///////////////////////// 获取商品尺码属性 END////////////////////
}
}
// 按照一下顺序进行 json 数据的填充
productResponse.setPropFlag(true);
productResponse.setProductPropSet(productPropSet);
productResponse.setPlatform(PlatformEnum.ZARA.getValue());
productResponse.setPromotionList(promotionList);
productResponse.setOriginalPriceList(originalPriceList);
productResponse.setItemInfo(itemInfo);
productResponse.setDynStock(dynStock);
return productResponse;
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论