Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
Z
zion
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
zhengfg
zion
Commits
5f8ad000
提交
5f8ad000
authored
10月 29, 2019
作者:
梁业锦
💬
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Merge branch 'master' of D:\diaoyun\zion with conflicts.
上级
0e0672de
全部展开
显示空白字符变更
内嵌
并排
正在显示
36 个修改的文件
包含
2818 行增加
和
123 行删除
+2818
-123
Test.json
Test.json
+587
-0
SpiderSpecification.md
doc/SpiderSpecification.md
+54
-42
ZionApplication.java
src/main/java/com/diaoyun/zion/ZionApplication.java
+4
-2
IItemSpider.java
...ain/java/com/diaoyun/zion/chinafrica/bis/IItemSpider.java
+10
-3
AdidasSpider.java
...va/com/diaoyun/zion/chinafrica/bis/impl/AdidasSpider.java
+17
-13
AfricaShopItemSpider.java
...iaoyun/zion/chinafrica/bis/impl/AfricaShopItemSpider.java
+1
-1
EspritSpider.java
...va/com/diaoyun/zion/chinafrica/bis/impl/EspritSpider.java
+4
-0
GapItemSpider.java
...a/com/diaoyun/zion/chinafrica/bis/impl/GapItemSpider.java
+3
-0
LeviSpider.java
...java/com/diaoyun/zion/chinafrica/bis/impl/LeviSpider.java
+4
-0
LilySpider.java
...java/com/diaoyun/zion/chinafrica/bis/impl/LilySpider.java
+57
-0
MassimoduttiSpider.java
.../diaoyun/zion/chinafrica/bis/impl/MassimoduttiSpider.java
+5
-7
MocoSpider.java
...java/com/diaoyun/zion/chinafrica/bis/impl/MocoSpider.java
+4
-0
NikeItemSpider.java
.../com/diaoyun/zion/chinafrica/bis/impl/NikeItemSpider.java
+1
-0
OchirlySpider.java
...a/com/diaoyun/zion/chinafrica/bis/impl/OchirlySpider.java
+95
-0
PullandbearSpider.java
...m/diaoyun/zion/chinafrica/bis/impl/PullandbearSpider.java
+3
-5
UnderArmourSpider.java
...m/diaoyun/zion/chinafrica/bis/impl/UnderArmourSpider.java
+54
-0
UniqloSpider.java
...va/com/diaoyun/zion/chinafrica/bis/impl/UniqloSpider.java
+3
-5
UrbanRevivoSpider.java
...m/diaoyun/zion/chinafrica/bis/impl/UrbanRevivoSpider.java
+57
-0
PlatformEnum.java
.../java/com/diaoyun/zion/chinafrica/enums/PlatformEnum.java
+5
-1
ItemSpiderFactory.java
...om/diaoyun/zion/chinafrica/factory/ItemSpiderFactory.java
+39
-23
SpiderServiceImpl.java
...aoyun/zion/chinafrica/service/impl/SpiderServiceImpl.java
+12
-4
HttpClientUtil.java
...ain/java/com/diaoyun/zion/master/util/HttpClientUtil.java
+0
-2
JsoupUtil.java
src/main/java/com/diaoyun/zion/master/util/JsoupUtil.java
+4
-15
AdidasSpiderParse.java
...om/diaoyun/zion/master/util/spider/AdidasSpiderParse.java
+132
-0
EspritSpiderParse.java
...om/diaoyun/zion/master/util/spider/EspritSpiderParse.java
+4
-0
LeviSpiderParse.java
.../com/diaoyun/zion/master/util/spider/LeviSpiderParse.java
+4
-0
LilySpiderParse.java
.../com/diaoyun/zion/master/util/spider/LilySpiderParse.java
+128
-0
MassimoDuttiSpiderParse.java
...oyun/zion/master/util/spider/MassimoDuttiSpiderParse.java
+161
-0
MocoSpiderParse.java
.../com/diaoyun/zion/master/util/spider/MocoSpiderParse.java
+4
-0
OchirlySpiderParse.java
...m/diaoyun/zion/master/util/spider/OchirlySpiderParse.java
+152
-0
PullAndBearSpiderParse.java
...aoyun/zion/master/util/spider/PullAndBearSpiderParse.java
+160
-0
SpiderUtil.java
.../java/com/diaoyun/zion/master/util/spider/SpiderUtil.java
+442
-0
UnderArmourSpiderParse.java
...aoyun/zion/master/util/spider/UnderArmourSpiderParse.java
+137
-0
UniqloSpiderParse.java
...om/diaoyun/zion/master/util/spider/UniqloSpiderParse.java
+154
-0
UrbanRevivoSpiderParse.java
...aoyun/zion/master/util/spider/UrbanRevivoSpiderParse.java
+146
-0
ZaraSpiderParse.java
.../com/diaoyun/zion/master/util/spider/ZaraSpiderParse.java
+171
-0
没有找到文件。
Test.json
0 → 100644
浏览文件 @
5f8ad000
差异被折叠。
点击展开。
doc/SpiderSpecification.md
浏览文件 @
5f8ad000
...
...
@@ -21,35 +21,6 @@
> 注意爬虫的命名
# 爬虫步骤
## 目的
帮助不能使用国内购物平台的用户进行
**代购服务**
,而要进行代购,就要
**帮助他们下单**
。为了帮助用户下单,很重要的
一步就是要
**获取平台的商品的规格**
;让用户可以在浏览的时候,可以让他们在我们app上选择相应规格的商品
## 分析页面数据
首先要明白的是:App页面传给我们的只有原始商品的连接,为了获取页面上的商品信息有两种方式:
-
分析
**页面**
构成,例如:Zara 爬虫
-
在某个地方会存在json数据的传递
-
嵌套在Html页面中的各种数据
-
分析页面调用接口后的返回数据,例如:Uniqlo 优衣库爬虫
## 页面中存在Json数据传递的--示例:Zara
### 1.随便点击一个商品详情页<br>

### 2.通过商品的一些关键信息进行搜索<br>

### 3.检索信息(关键步骤)
-
(1)
**感觉可能**
这是相关的商品详情信息,而且是
**Json格式**
的数据
-
(2) 通过
[
Json格式化工具:http://www.bejson.com/jsonviewernew/
](
http://www.bejson.com/jsonviewernew/
)
来格式化Json数据
-
(3) 再次通过关键搜索诸如
**价格**
、
**尺寸**
等,检查数据是否是我们想要的、是否是完整的,如果不是重复(1)、(2)步骤继续搜寻
<br>

-
(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>

### 2.通过商品的一些关键信息进行搜索<br>

### 3.检索信息(关键步骤)
-
(1)
**感觉可能**
这是相关的商品详情信息,而且是
**Json格式**
的数据
-
(2) 通过
[
Json格式化工具:http://www.bejson.com/jsonviewernew/
](
http://www.bejson.com/jsonviewernew/
)
来格式化Json数据
-
(3) 再次通过关键搜索诸如
**价格**
、
**尺寸**
等,检查数据是否是我们想要的、是否是完整的,如果不是重复(1)、(2)步骤继续搜寻
<br>

-
(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)
...
...
src/main/java/com/diaoyun/zion/ZionApplication.java
浏览文件 @
5f8ad000
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
{
}
}
src/main/java/com/diaoyun/zion/chinafrica/bis/IItemSpider.java
浏览文件 @
5f8ad000
...
...
@@ -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
,
Interrupted
Exception
,
TimeoutException
;
JSONObject
captureItem
(
String
targetUrl
)
throws
InterruptedException
,
IOException
,
ExecutionException
,
URISyntax
Exception
,
TimeoutException
;
}
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/AdidasSpider.java
浏览文件 @
5f8ad000
...
...
@@ -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
);
}
}
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/AfricaShopItemSpider.java
浏览文件 @
5f8ad000
...
...
@@ -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
;
...
...
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/EspritSpider.java
0 → 100644
浏览文件 @
5f8ad000
package
com
.
diaoyun
.
zion
.
chinafrica
.
bis
.
impl
;
public
class
EspritSpider
{
}
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/GapItemSpider.java
浏览文件 @
5f8ad000
...
...
@@ -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
{
...
...
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/LeviSpider.java
0 → 100644
浏览文件 @
5f8ad000
package
com
.
diaoyun
.
zion
.
chinafrica
.
bis
.
impl
;
public
class
LeviSpider
{
}
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/LilySpider.java
0 → 100644
浏览文件 @
5f8ad000
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
);
}
}
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/MassimoduttiSpider.java
浏览文件 @
5f8ad000
...
...
@@ -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
.
formatMassimoDutti
ProductResponse
(
resultObj
,
pId
);
ProductResponse
productResponse
=
MassimoDuttiSpiderParse
.
format
ProductResponse
(
resultObj
,
pId
);
resultObj
=
JSONObject
.
fromObject
(
productResponse
);
TranslateHelper
.
translateProductResponse
(
resultObj
);
return
resultObj
;
...
...
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/MocoSpider.java
0 → 100644
浏览文件 @
5f8ad000
package
com
.
diaoyun
.
zion
.
chinafrica
.
bis
.
impl
;
public
class
MocoSpider
{
}
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/NikeItemSpider.java
浏览文件 @
5f8ad000
...
...
@@ -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
;
...
...
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/OchirlySpider.java
0 → 100644
浏览文件 @
5f8ad000
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
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/PullandbearSpider.java
浏览文件 @
5f8ad000
...
...
@@ -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
.
formatPullAndBear
ProductResponse
(
resultJson
,
pId
);
ProductResponse
productResponse
=
PullAndBearSpiderParse
.
format
ProductResponse
(
resultJson
,
pId
);
resultJson
=
JSONObject
.
fromObject
(
productResponse
);
// 翻译
TranslateHelper
.
translateProductResponse
(
resultJson
);
...
...
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/UnderArmourSpider.java
0 → 100644
浏览文件 @
5f8ad000
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
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/UniqloSpider.java
浏览文件 @
5f8ad000
...
...
@@ -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
.
formatUniqlo
ProductResponse
(
resultJson
,
priceJson
,
pId
);
ProductResponse
productResponse
=
UniqloSpiderParse
.
format
ProductResponse
(
resultJson
,
priceJson
,
pId
);
resultJson
=
JSONObject
.
fromObject
(
productResponse
);
// 翻译
TranslateHelper
.
translateProductResponse
(
resultJson
);
...
...
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/UrbanRevivoSpider.java
0 → 100644
浏览文件 @
5f8ad000
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
src/main/java/com/diaoyun/zion/chinafrica/enums/PlatformEnum.java
浏览文件 @
5f8ad000
...
...
@@ -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"
);
...
...
src/main/java/com/diaoyun/zion/chinafrica/factory/ItemSpiderFactory.java
浏览文件 @
5f8ad000
...
...
@@ -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
;
}
}
...
...
src/main/java/com/diaoyun/zion/chinafrica/service/impl/SpiderServiceImpl.java
浏览文件 @
5f8ad000
...
...
@@ -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
;
...
...
src/main/java/com/diaoyun/zion/master/util/HttpClientUtil.java
浏览文件 @
5f8ad000
...
...
@@ -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
...
...
src/main/java/com/diaoyun/zion/master/util/JsoupUtil.java
浏览文件 @
5f8ad000
...
...
@@ -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 爬虫的主要数据
...
...
src/main/java/com/diaoyun/zion/master/util/spider/AdidasSpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
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
;
}
}
src/main/java/com/diaoyun/zion/master/util/spider/EspritSpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
package
com
.
diaoyun
.
zion
.
master
.
util
.
spider
;
public
class
EspritSpiderParse
{
}
src/main/java/com/diaoyun/zion/master/util/spider/LeviSpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
package
com
.
diaoyun
.
zion
.
master
.
util
.
spider
;
public
class
LeviSpiderParse
{
}
src/main/java/com/diaoyun/zion/master/util/spider/LilySpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
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
;
}
}
src/main/java/com/diaoyun/zion/master/util/spider/MassimoDuttiSpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
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
;
}
}
src/main/java/com/diaoyun/zion/master/util/spider/MocoSpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
package
com
.
diaoyun
.
zion
.
master
.
util
.
spider
;
public
class
MocoSpiderParse
{
}
src/main/java/com/diaoyun/zion/master/util/spider/OchirlySpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
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
;
}
}
src/main/java/com/diaoyun/zion/master/util/spider/PullAndBearSpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
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
;
}
}
src/main/java/com/diaoyun/zion/master/util/SpiderUtil.java
→
src/main/java/com/diaoyun/zion/master/util/
spider/
SpiderUtil.java
浏览文件 @
5f8ad000
差异被折叠。
点击展开。
src/main/java/com/diaoyun/zion/master/util/spider/UnderArmourSpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
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
;
}
}
src/main/java/com/diaoyun/zion/master/util/spider/UniqloSpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
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
;
}
}
src/main/java/com/diaoyun/zion/master/util/spider/UrbanRevivoSpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
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
;
}
}
src/main/java/com/diaoyun/zion/master/util/spider/ZaraSpiderParse.java
0 → 100644
浏览文件 @
5f8ad000
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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论