Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
Z
zion
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
zhengfg
zion
Commits
15724fe1
提交
15724fe1
authored
10月 25, 2019
作者:
梁业锦
💬
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
增加了Pull And Bear的爬虫
上级
a0445920
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
256 行增加
和
41 行删除
+256
-41
SpiderSpecification.md
doc/SpiderSpecification.md
+27
-9
PullandbearSpider.java
...m/diaoyun/zion/chinafrica/bis/impl/PullandbearSpider.java
+17
-6
UniqloSpider.java
...va/com/diaoyun/zion/chinafrica/bis/impl/UniqloSpider.java
+1
-10
JsoupUtil.java
src/main/java/com/diaoyun/zion/master/util/JsoupUtil.java
+34
-16
SpiderUtil.java
src/main/java/com/diaoyun/zion/master/util/SpiderUtil.java
+177
-0
没有找到文件。
doc/SpiderSpecification.md
浏览文件 @
15724fe1
...
...
@@ -25,7 +25,7 @@
### Pull and Bear
-
主页:https://www.pullandbear.cn/cn/%E5%A5%B3%E5%A3%AB-c1030204574.html
-
命名:pullandbear
-
爬虫进度:
存在缺陷
-
爬虫进度:
**已完成**
-
有反爬机制,有时会直接失效,不稳定
### Gap
-
主页:https://www.gap.cn/
...
...
@@ -38,9 +38,9 @@
### Uniqlo
-
主页:https://www.uniqlo.cn/UNIQLO_U19FW_MEN.html
-
命名:uniqlo
-
爬虫进度:
存在缺陷--
-
图片:会直接下载
-
无法获取折扣后的价格
-
爬虫进度:
**已完成**
-
可能存在的缺陷:
-
图片的路径是直接下载图片
### Nike
-
主页:https://www.nike.com/cn
-
命名:nike
...
...
@@ -53,7 +53,7 @@
-
主页:https://www2.hm.com/zh_cn/
-
命名:hm
-
爬虫进度:已能获取到数据
-
图片路径处理难度太多
-
Json被做了一些难处理的封装,现有工具无法将其转换为Json格式
-
商品颜色通过商品详情页的url来区分,暂未找到规律
### LiLy
-
主页:http://www.lily.sh.cn/webapp/wcs/stores/servlet/lilystore
...
...
@@ -102,11 +102,22 @@
-
数据来源
-
商品详情:https://www.massimodutti.cn/cn/%E5%A5%B3%E8%A3%85/%E7%B3%BB%E5%88%97/%E8%A1%AC%E8%A1%AB%E5%92%8C%E7%BD%A9%E8%A1%AB/%E8%A1%AC%E8%A1%AB/%E6%BB%91%E9%9B%AA%E9%A3%8E%E7%B3%BB%E5%88%97%E9%A5%B0%E5%8F%A3%E8%A2%8B%E8%A1%AC%E8%A1%AB-c1718602p8730105.html?colorId=420&categoryId=1718602
-
数据接口:https://www.massimodutti.cn/itxrest/2/catalog/store/35009478/30359500/category/0/product/8730105/detail?languageId=-7&appId=1
### COACH
-
主页:https://china.coach.com/women.html
-
命名:coach
-
爬虫进度:
### Revolve
-
主页:https://www.revolve.com/wrangler/br/57f1a1/?utm_source=baidu&utm_medium=cpc&utm_campaign=intl_P_cn-d-Wrangler
-
命名:reolve
-
爬虫进度:
### Vans
-
主页:https://vans.com.cn/gallery-index---0---36.html
-
命名:Vans
### 待选爬虫网站:
-
18,https://www.massimodutti.cn/cn/男装/季末折扣/休闲西装-c1745921.html ( 西班牙品牌)
-
19,https://china.coach.com/women.html
-
20,https://www.revolve.com/wrangler/br/57f1a1/?utm_source=baidu&utm_medium=cpc&utm_campaign=intl_P_cn-d-Wrangler (美国轻奢品牌集合网站)
-
21,https://vans.com.cn/gallery-index---0---36.html
-
22,https://zarahome.tmall.com/?spm=a1z10.3-b-s.1997427721.d4918089.7b872e00zWrHhi
-
23,https://oysho.tmall.com/ (SPORT WEAR)
...
...
@@ -124,6 +135,13 @@
## 爬虫Json数据返回规范
### 封装类 [ProductResponse](../src/main/java/com/diaoyun/zion/chinafrica/vo/ProductResponse.java)
封装类的属性已经说明了爬虫需要爬取的数据有哪一些
-
skuId 标识规范:;
[
颜色id
]
;
[
尺寸id
]
;
-
该 id 通过爬取
**颜色**
与
**尺寸**
对应数据时获取到的唯一标识
-
用于标识
**库存**
与
**价格**
#### 按照 Nike 爬虫返回的数据进行封装
│── data 数据
<br>
│ │── dynStock 库存
<br>
...
...
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/PullandbearSpider.java
浏览文件 @
15724fe1
...
...
@@ -2,7 +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
net.sf.json.JSONArray
;
import
net.sf.json.JSONObject
;
import
org.slf4j.Logger
;
...
...
@@ -15,8 +18,9 @@ import java.util.concurrent.ExecutionException;
import
java.util.concurrent.TimeoutException
;
/**
* 西班牙年轻时尚品牌-
pullandb
ear 数据爬虫
* 西班牙年轻时尚品牌-
PullAndB
ear 数据爬虫
*
* @author 爱酱油不爱醋
*/
@Component
(
"pullandbearSpider"
)
public
class
PullandbearSpider
implements
IItemSpider
{
...
...
@@ -24,20 +28,27 @@ public class PullandbearSpider implements IItemSpider {
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
PullandbearSpider
.
class
);
/**
* Pull
and
Bear 商品详情链接
* Pull
And
Bear 商品详情链接
*/
private
static
final
String
PULL_AND_BEAR_URL
=
"https://www.pullandbear.cn/itxrest/2/catalog/store/24009528/20309423/category/0/product/"
;
/**
* PullAndBear 数据爬虫
* @see com.diaoyun.zion.chinafrica.service.impl.SpiderServiceImpl#judgeUrlType 修改商品详情页路径
* @see SpiderUtil#formatPullAndBearProductResponse 格式化数据方法
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
*/
@Override
public
JSONObject
captureItem
(
String
targetUrl
)
throws
URISyntaxException
,
IOException
,
ExecutionException
,
InterruptedException
,
TimeoutException
{
// 提取链接中的商品 id 信息
String
pId
=
targetUrl
.
substring
(
targetUrl
.
lastIndexOf
(
"p"
)+
1
,
targetUrl
.
lastIndexOf
(
".html"
));
// 组成链接并获取商品详情信息的 Json
targetUrl
=
PULL_AND_BEAR_URL
+
pId
+
"/detail?languageId=-7&appId=1"
;
// 获取网页内容
String
content
=
HttpClientUtil
.
getContentByUrl
(
targetUrl
,
PlatformEnum
.
PULLANDBEAR
.
getValue
());
// 转换为Json格式
JSONObject
resultJson
=
JSONObject
.
fromObject
(
content
);
ProductResponse
productResponse
=
SpiderUtil
.
formatPullAndBearProductResponse
(
resultJson
,
pId
);
resultJson
=
JSONObject
.
fromObject
(
productResponse
);
// 翻译
TranslateHelper
.
translateProductResponse
(
resultJson
);
return
resultJson
;
}
...
...
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/UniqloSpider.java
浏览文件 @
15724fe1
...
...
@@ -34,6 +34,7 @@ public class UniqloSpider implements IItemSpider {
/**
* Uniqlo 数据爬虫
* @see com.diaoyun.zion.chinafrica.service.impl.SpiderServiceImpl#judgeUrlType 修改商品详情页路径
* @see
* @see SpiderUtil#formatUniqloProductResponse 格式化数据方法
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
...
...
@@ -57,14 +58,4 @@ public class UniqloSpider implements IItemSpider {
return
resultJson
;
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
String
targetUrl
=
"https://www.uniqlo.cn/product-detail.html?productCode=u0000000001970"
;
// 截取链接中的商品 id
String
[]
split
=
targetUrl
.
split
(
"productCode="
);
String
pId
=
split
[
1
];
targetUrl
=
UNIQLO_URL
+
"zh_CN/"
+
pId
+
".json"
;
String
content
=
HttpClientUtil
.
getContentByUrl
(
targetUrl
,
PlatformEnum
.
UNIQLO
.
getValue
());
System
.
out
.
println
(
content
);
}
}
src/main/java/com/diaoyun/zion/master/util/JsoupUtil.java
浏览文件 @
15724fe1
...
...
@@ -150,22 +150,6 @@ public class JsoupUtil {
}
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
String
targetUrl
=
"https://www2.hm.com/zh_cn/productpage.0809313001.html"
;
String
content
=
HttpClientUtil
.
getContentByUrl
(
targetUrl
,
PlatformEnum
.
HM
.
getValue
());
String
detailStr
=
getScriptContent
(
content
,
"productArticleDetails"
);
int
firstBrackets
=
detailStr
.
indexOf
(
"{"
);
int
lastbrackets
=
detailStr
.
lastIndexOf
(
"}"
);
String
resultStr
=
detailStr
.
substring
(
firstBrackets
,
lastbrackets
+
1
);
int
firstImage
=
detailStr
.
indexOf
(
"'images':["
);
int
lastImage
=
detailStr
.
lastIndexOf
(
"'video':"
);
detailStr
=
detailStr
.
substring
(
firstImage
,
lastImage
);
resultStr
=
resultStr
.
replace
(
detailStr
,
""
);
JSONObject
resultObj
=
JSONObject
.
fromObject
(
resultStr
);
System
.
out
.
println
(
resultObj
);
}
/**
* 解析出商品详情
*
...
...
@@ -260,6 +244,40 @@ public class JsoupUtil {
return
dataMap
;
}
/**
* 获取 H&M 爬虫的主要数据
* @param content
* @throws Exception
*/
public
static
JSONObject
getHMJsonData
(
String
content
)
{
String
detailStr
=
getScriptContent
(
content
,
"productArticleDetails"
);
int
firstBrackets
=
detailStr
.
indexOf
(
"{"
);
int
lastbrackets
=
detailStr
.
lastIndexOf
(
"}"
);
String
resultStr
=
detailStr
.
substring
(
firstBrackets
,
lastbrackets
+
1
);
int
firstImage
=
detailStr
.
indexOf
(
"'images':["
);
int
lastImage
=
detailStr
.
lastIndexOf
(
"'video':"
);
detailStr
=
detailStr
.
substring
(
firstImage
,
lastImage
);
resultStr
=
resultStr
.
replace
(
detailStr
,
""
);
JSONObject
resultObj
=
JSONObject
.
fromObject
(
resultStr
);
return
resultObj
;
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
String
targetUrl
=
"https://www2.hm.com/zh_cn/productpage.0754698003.html"
;
String
content
=
HttpClientUtil
.
getContentByUrl
(
targetUrl
,
PlatformEnum
.
ZARA
.
getValue
());
String
detailStr
=
getScriptContent
(
content
,
"productArticleDetails"
);
int
firstBrackets
=
detailStr
.
indexOf
(
"{"
);
int
lastbrackets
=
detailStr
.
lastIndexOf
(
"}"
);
String
resultStr
=
detailStr
.
substring
(
firstBrackets
,
lastbrackets
+
1
);
resultStr
=
resultStr
.
replace
(
"isDesktop ? "
,
""
);
String
regexp
=
"\'"
;
resultStr
=
resultStr
.
replaceAll
(
regexp
,
"\""
);
JSONObject
resultObj
=
JSONObject
.
fromObject
(
resultStr
);
System
.
err
.
println
(
resultObj
);
}
/**
* 根据script id获取内容
* @param content
...
...
src/main/java/com/diaoyun/zion/master/util/SpiderUtil.java
浏览文件 @
15724fe1
...
...
@@ -5,6 +5,7 @@ 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.stripe.model.Product
;
import
net.sf.json.JSONArray
;
import
net.sf.json.JSONObject
;
import
org.apache.commons.lang3.StringUtils
;
...
...
@@ -827,4 +828,180 @@ public class SpiderUtil {
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
* @param dataMap 主要的 json 数据
* @return 格式化后的数据
*/
public
static
ProductResponse
formatHMProductResponse
(
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
();
// 按照一下顺序进行 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
;
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论