Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
Z
zion
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
zhengfg
zion
Commits
e768cea5
提交
e768cea5
authored
10月 20, 2019
作者:
梁业锦
💬
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
添加了基于本项目的爬虫文档;已完成Zara与优衣库的爬虫格式化;优衣库存在缺陷,
暂且不可用
上级
d2f65e7c
全部展开
显示空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
806 行增加
和
111 行删除
+806
-111
README.md
README.md
+5
-0
SpiderSpecification.md
doc/SpiderSpecification.md
+459
-0
NikeItemSpider.java
.../com/diaoyun/zion/chinafrica/bis/impl/NikeItemSpider.java
+0
-1
PullandbearSpider.java
...m/diaoyun/zion/chinafrica/bis/impl/PullandbearSpider.java
+0
-2
UniqloSpider.java
...va/com/diaoyun/zion/chinafrica/bis/impl/UniqloSpider.java
+13
-14
ZaraSpider.java
...java/com/diaoyun/zion/chinafrica/bis/impl/ZaraSpider.java
+7
-68
PlatformEnum.java
.../java/com/diaoyun/zion/chinafrica/enums/PlatformEnum.java
+2
-0
DynStock.java
src/main/java/com/diaoyun/zion/chinafrica/vo/DynStock.java
+1
-0
ProductProp.java
...main/java/com/diaoyun/zion/chinafrica/vo/ProductProp.java
+5
-3
ProductResponse.java
.../java/com/diaoyun/zion/chinafrica/vo/ProductResponse.java
+35
-11
JsoupUtil.java
src/main/java/com/diaoyun/zion/master/util/JsoupUtil.java
+10
-4
SpiderUtil.java
src/main/java/com/diaoyun/zion/master/util/SpiderUtil.java
+269
-8
没有找到文件。
README.md
浏览文件 @
e768cea5
...
@@ -8,6 +8,11 @@
...
@@ -8,6 +8,11 @@
*
自定义的一些配置,比如邮箱、stripe账号、腾讯ai相关的配置等等
*
自定义的一些配置,比如邮箱、stripe账号、腾讯ai相关的配置等等
3.
logback-spring.xml
3.
logback-spring.xml
*
日志配置文件
*
日志配置文件
# 爬虫规范及文档
[
爬虫文档链接
](
../doc/SpiderSpecification.md
)
# 项目层次结构
# 项目层次结构
项目大致分为两个包和相关的资源文件,两个包分别是com.diaoyun.zion.master和com.diaoyun.zion.chinafrica。
项目大致分为两个包和相关的资源文件,两个包分别是com.diaoyun.zion.master和com.diaoyun.zion.chinafrica。
1.
master这个包下面放的是项目通用的类,比如项目模块配置类、异常处理、spring security相关的东西。
1.
master这个包下面放的是项目通用的类,比如项目模块配置类、异常处理、spring security相关的东西。
...
...
doc/SpiderSpecification.md
0 → 100644
浏览文件 @
e768cea5
差异被折叠。
点击展开。
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/NikeItemSpider.java
浏览文件 @
e768cea5
...
@@ -21,7 +21,6 @@ public class NikeItemSpider implements IItemSpider {
...
@@ -21,7 +21,6 @@ public class NikeItemSpider implements IItemSpider {
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
NikeItemSpider
.
class
);
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
NikeItemSpider
.
class
);
@Override
@Override
public
JSONObject
captureItem
(
String
targetUrl
)
throws
URISyntaxException
,
IOException
,
InterruptedException
,
ExecutionException
,
TimeoutException
{
public
JSONObject
captureItem
(
String
targetUrl
)
throws
URISyntaxException
,
IOException
,
InterruptedException
,
ExecutionException
,
TimeoutException
{
JSONObject
resultObj
;
JSONObject
resultObj
;
...
...
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/PullandbearSpider.java
浏览文件 @
e768cea5
...
@@ -17,8 +17,6 @@ import java.util.concurrent.TimeoutException;
...
@@ -17,8 +17,6 @@ import java.util.concurrent.TimeoutException;
/**
/**
* 西班牙年轻时尚品牌-pullandbear 数据爬虫
* 西班牙年轻时尚品牌-pullandbear 数据爬虫
*
*
* TODO 图片路径未处理
* 图片路径为:
*/
*/
@Component
(
"pullandbearSpider"
)
@Component
(
"pullandbearSpider"
)
public
class
PullandbearSpider
implements
IItemSpider
{
public
class
PullandbearSpider
implements
IItemSpider
{
...
...
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/UniqloSpider.java
浏览文件 @
e768cea5
...
@@ -2,7 +2,10 @@ package com.diaoyun.zion.chinafrica.bis.impl;
...
@@ -2,7 +2,10 @@ package com.diaoyun.zion.chinafrica.bis.impl;
import
com.diaoyun.zion.chinafrica.bis.IItemSpider
;
import
com.diaoyun.zion.chinafrica.bis.IItemSpider
;
import
com.diaoyun.zion.chinafrica.enums.PlatformEnum
;
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.HttpClientUtil
;
import
com.diaoyun.zion.master.util.SpiderUtil
;
import
com.diaoyun.zion.master.util.TranslateHelper
;
import
net.sf.json.JSONArray
;
import
net.sf.json.JSONArray
;
import
net.sf.json.JSONObject
;
import
net.sf.json.JSONObject
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
...
@@ -17,8 +20,9 @@ import java.util.concurrent.TimeoutException;
...
@@ -17,8 +20,9 @@ import java.util.concurrent.TimeoutException;
/**
/**
* 优衣库数据爬虫
* 优衣库数据爬虫
*
*
* TODO 图片路径未处理
* 图片路径为:"https://www.uniqlo.cn/hmall/test/" + 商品id + "/sku/561/" + 商品图片id + ".jpg"
* 图片路径为:"https://www.uniqlo.cn/hmall/test/" + 商品id + "/sku/40/" + 商品图片id + ".jpg"
*
* @author 爱酱油不爱醋
*/
*/
@Component
(
"uniqloSpider"
)
@Component
(
"uniqloSpider"
)
public
class
UniqloSpider
implements
IItemSpider
{
public
class
UniqloSpider
implements
IItemSpider
{
...
@@ -37,18 +41,13 @@ public class UniqloSpider implements IItemSpider {
...
@@ -37,18 +41,13 @@ public class UniqloSpider implements IItemSpider {
// 获取网页内容
// 获取网页内容
String
content
=
HttpClientUtil
.
getContentByUrl
(
targetUrl
,
PlatformEnum
.
UNIQLO
.
getValue
());
String
content
=
HttpClientUtil
.
getContentByUrl
(
targetUrl
,
PlatformEnum
.
UNIQLO
.
getValue
());
// 转换为 json
// 转换为 json
JSONObject
json
=
JSONObject
.
fromObject
(
content
);
JSONObject
resultJson
=
JSONObject
.
fromObject
(
content
);
// 商品id
// 按照封装规范封装商品数据
String
pName
=
json
.
getJSONObject
(
"summary"
).
getString
(
"name"
);
ProductResponse
productResponse
=
SpiderUtil
.
formatUniqloProductResponse
(
resultJson
,
pId
);
// 商品价格
resultJson
=
JSONObject
.
fromObject
(
productResponse
);
String
pPrice
=
json
.
getJSONObject
(
"summary"
).
getString
(
"originPrice"
);
// 翻译
// 格式化数据
TranslateHelper
.
translateProductResponse
(
resultJson
);
JSONArray
rowsJson
=
json
.
getJSONArray
(
"rows"
);
return
resultJson
;
JSONObject
returnJson
=
new
JSONObject
();
returnJson
.
put
(
"name"
,
pName
);
returnJson
.
put
(
"price"
,
pPrice
);
returnJson
.
elementOpt
(
"data"
,
rowsJson
);
return
returnJson
;
}
}
}
}
src/main/java/com/diaoyun/zion/chinafrica/bis/impl/ZaraSpider.java
浏览文件 @
e768cea5
...
@@ -22,7 +22,8 @@ import java.util.concurrent.TimeoutException;
...
@@ -22,7 +22,8 @@ import java.util.concurrent.TimeoutException;
/**
/**
* Zara西班牙时尚品牌数据爬虫
* Zara西班牙时尚品牌数据爬虫
* TODO 数据未处理完全
*
* @author 爱酱油不爱醋
*/
*/
@Component
(
"zaraSpider"
)
@Component
(
"zaraSpider"
)
public
class
ZaraSpider
implements
IItemSpider
{
public
class
ZaraSpider
implements
IItemSpider
{
...
@@ -37,76 +38,14 @@ public class ZaraSpider implements IItemSpider {
...
@@ -37,76 +38,14 @@ public class ZaraSpider implements IItemSpider {
// 获取url中的网页内容
// 获取url中的网页内容
String
content
=
HttpClientUtil
.
getContentByUrl
(
targetUrl
,
PlatformEnum
.
ZARA
.
getValue
());
String
content
=
HttpClientUtil
.
getContentByUrl
(
targetUrl
,
PlatformEnum
.
ZARA
.
getValue
());
// 截取主要的 Json 内容
// 截取主要的 Json 内容
resultObj
=
JsoupUtil
.
getZara
(
content
);
resultObj
=
JsoupUtil
.
getZaraJsonData
(
content
);
ProductResponse
productResponse
=
SpiderUtil
.
formatNikeProductResponse
(
resultObj
);
// 按照封装规范封装商品数据
ProductResponse
productResponse
=
SpiderUtil
.
formatZaraProductResponse
(
resultObj
);
// 将封装数据转换为 json 数据
resultObj
=
JSONObject
.
fromObject
(
productResponse
);
resultObj
=
JSONObject
.
fromObject
(
productResponse
);
//翻译
//
翻译
TranslateHelper
.
translateProductResponse
(
resultObj
);
TranslateHelper
.
translateProductResponse
(
resultObj
);
return
resultObj
;
return
resultObj
;
}
}
/**
* 根据首位字符串内容进行截取
* @param jsonStr
* @param startStr 起始字符串
* @param lastStr 结尾字符串(不包含)
* @return
*/
private
static
String
getDataJson
(
String
jsonStr
,
String
startStr
,
String
lastStr
)
{
int
startIndex
=
jsonStr
.
indexOf
(
startStr
);
int
lastIndex
=
jsonStr
.
lastIndexOf
(
lastStr
);
return
jsonStr
.
substring
(
startIndex
,
lastIndex
);
}
public
static
void
main
(
String
[]
args
)
throws
IOException
,
URISyntaxException
{
// URL链接
String
targetUrl
=
"https://www.zara.cn/cn/zh/%E5%BA%9C%E7%BB%B8%E9%95%BF%E7%89%88%E8%A1%AC%E8%A1%AB-p08053157.html?v1=31979171&v2=1319321"
;
// 获取网页内容
String
content
=
HttpClientUtil
.
getContentByUrl
(
targetUrl
,
PlatformEnum
.
ZARA
.
getValue
());
// 截取主要的商品数据
int
labelHeadIndex
=
content
.
indexOf
(
"dataLayer"
);
int
labelTailIndex
=
content
.
lastIndexOf
(
";window.zara.viewPayload"
);
String
abv
=
content
.
substring
(
labelHeadIndex
,
labelTailIndex
).
replace
(
"dataLayer = "
,
""
);
System
.
err
.
println
(
abv
);
// 转换为 Json 格式
JSONObject
json
=
JSONObject
.
fromObject
(
abv
);
// System.err.println(json);
// product 对象节点
JSONObject
responseData
=
json
.
getJSONObject
(
"product"
);
// System.err.println(responseData);
// detail 对象节点
JSONObject
details
=
responseData
.
getJSONObject
(
"detail"
);
// System.err.println(details);
// colors 数组节点
JSONArray
colorsArray
=
details
.
getJSONArray
(
"colors"
);
Map
<
Integer
,
JSONObject
>
colorMap
=
new
HashMap
<>();
for
(
int
i
=
0
;
i
<
colorsArray
.
size
();
i
++)
{
colorMap
.
put
(
i
,
colorsArray
.
getJSONObject
(
i
));
}
System
.
out
.
println
(
colorMap
);
// TODO 取出颜色属性
// sizes 数组节点
Map
<
Integer
,
JSONObject
>
sizesMap
=
new
HashMap
<>();
for
(
Map
.
Entry
<
Integer
,
JSONObject
>
entry
:
colorMap
.
entrySet
()){
// 遍历出每个 colors 对象节点
JSONObject
colors
=
entry
.
getValue
();
JSONArray
sizesArray
=
colors
.
getJSONArray
(
"sizes"
);
for
(
int
i
=
0
;
i
<
sizesArray
.
size
();
i
++)
{
sizesMap
.
put
(
i
,
sizesArray
.
getJSONObject
(
i
));
}
}
System
.
out
.
println
(
sizesMap
);
// TODO 取出价格和尺码属性
// TODO 取出图片属性(图片实体类未知)
}
}
}
src/main/java/com/diaoyun/zion/chinafrica/enums/PlatformEnum.java
浏览文件 @
e768cea5
...
@@ -29,10 +29,12 @@ public enum PlatformEnum implements EnumItemable<PlatformEnum> {
...
@@ -29,10 +29,12 @@ public enum PlatformEnum implements EnumItemable<PlatformEnum> {
this
.
value
=
value
;
this
.
value
=
value
;
}
}
@Override
public
String
getLabel
()
{
public
String
getLabel
()
{
return
this
.
label
;
return
this
.
label
;
}
}
@Override
public
String
getValue
()
{
public
String
getValue
()
{
return
this
.
value
;
return
this
.
value
;
}
}
...
...
src/main/java/com/diaoyun/zion/chinafrica/vo/DynStock.java
浏览文件 @
e768cea5
...
@@ -6,6 +6,7 @@ import java.util.List;
...
@@ -6,6 +6,7 @@ import java.util.List;
* 库存
* 库存
*/
*/
public
class
DynStock
{
public
class
DynStock
{
//可用总的库存数
//可用总的库存数
private
int
sellableQuantity
;
private
int
sellableQuantity
;
//sku对应的库存数
//sku对应的库存数
...
...
src/main/java/com/diaoyun/zion/chinafrica/vo/ProductProp.java
浏览文件 @
e768cea5
...
@@ -47,11 +47,13 @@ public class ProductProp {
...
@@ -47,11 +47,13 @@ public class ProductProp {
@Override
@Override
public
boolean
equals
(
Object
obj
)
{
public
boolean
equals
(
Object
obj
)
{
if
(
obj
==
null
)
if
(
obj
==
null
)
{
return
false
;
return
false
;
if
(
this
==
obj
)
}
if
(
this
==
obj
)
{
return
true
;
return
true
;
if
(
obj
instanceof
ProductProp
)
{
}
if
(
obj
instanceof
ProductProp
)
{
ProductProp
productProp
=(
ProductProp
)
obj
;
ProductProp
productProp
=(
ProductProp
)
obj
;
if
(
productProp
.
propId
.
equals
(
this
.
propId
))
{
if
(
productProp
.
propId
.
equals
(
this
.
propId
))
{
return
true
;
return
true
;
...
...
src/main/java/com/diaoyun/zion/chinafrica/vo/ProductResponse.java
浏览文件 @
e768cea5
...
@@ -6,30 +6,54 @@ import java.util.Set;
...
@@ -6,30 +6,54 @@ import java.util.Set;
/**
/**
* 爬取数据后,返回页面的商品详情数据
* 爬取数据后,返回页面的商品详情数据
*
* @author G
*/
*/
public
class
ProductResponse
{
public
class
ProductResponse
{
//原始价格 有优惠的话还有优惠价
/**
* 原始价格 有优惠的话还有优惠价
*/
private
List
<
OriginalPrice
>
originalPriceList
;
private
List
<
OriginalPrice
>
originalPriceList
;
//是否包促销价格 true 有促销价格,false\null没有促销价格
/**
* 是否包促销价格 true 有促销价格,false\null没有促销价格
*/
private
boolean
promotionFlag
;
private
boolean
promotionFlag
;
//促销价格
/**
* 促销价格
*/
private
List
<
ProductPromotion
>
promotionList
;
private
List
<
ProductPromotion
>
promotionList
;
//原价一口价,就是商品一开始展示的价格,比如多sku多价格的情况下展示 18.80-49.90
/**
* 原价一口价,就是商品一开始展示的价格,比如多sku多价格的情况下展示 18.80-49.90
*/
private
String
price
;
private
String
price
;
//促销一口价
/**
* 促销一口价
*/
private
String
salePrice
;
private
String
salePrice
;
//是否包含库存信息 有些商品没有库存信息,可以当作是有货 true 有库存信息,false没有
/**
* 是否包含库存信息 有些商品没有库存信息,可以当作是有货 true 有库存信息,false没有
*/
private
boolean
stockFlag
;
private
boolean
stockFlag
;
//库存
/**
* 库存
*/
private
DynStock
dynStock
;
private
DynStock
dynStock
;
//是否包含商品属性,有些商品没有属性
/**
* 是否包含商品属性,有些商品没有属性
*/
private
boolean
propFlag
;
private
boolean
propFlag
;
//商品属性 颜色:红色,蓝色;尺码:S,l,M
/**
* 商品属性 颜色:红色,蓝色;尺码:S,l,M
*/
private
Map
<
String
,
Set
<
ProductProp
>>
productPropSet
;
private
Map
<
String
,
Set
<
ProductProp
>>
productPropSet
;
//商品信息
/**
* 商品信息
*/
private
ItemInfo
itemInfo
;
private
ItemInfo
itemInfo
;
//商品来源平台 PlatformEnum
/**
* 商品来源平台 PlatformEnum
*/
private
String
platform
;
private
String
platform
;
...
...
src/main/java/com/diaoyun/zion/master/util/JsoupUtil.java
浏览文件 @
e768cea5
package
com
.
diaoyun
.
zion
.
master
.
util
;
package
com
.
diaoyun
.
zion
.
master
.
util
;
import
com.diaoyun.zion.chinafrica.enums.PlatformEnum
;
import
net.sf.json.JSONObject
;
import
net.sf.json.JSONObject
;
import
org.apache.commons.text.StringEscapeUtils
;
import
org.apache.commons.text.StringEscapeUtils
;
import
org.jsoup.Jsoup
;
import
org.jsoup.Jsoup
;
...
@@ -10,6 +11,8 @@ import org.jsoup.select.Elements;
...
@@ -10,6 +11,8 @@ import org.jsoup.select.Elements;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
java.io.IOException
;
import
java.net.URISyntaxException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
...
@@ -18,8 +21,11 @@ import java.util.regex.Matcher;
...
@@ -18,8 +21,11 @@ import java.util.regex.Matcher;
import
java.util.regex.Pattern
;
import
java.util.regex.Pattern
;
public
class
JsoupUtil
{
public
class
JsoupUtil
{
public
static
String
unknow
=
"未知"
;
public
static
String
unknow
=
"未知"
;
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
JsoupUtil
.
class
);
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
JsoupUtil
.
class
);
/**
/**
* 获取淘宝商品详情的信息 店铺id 名字 主图 sibUrl 等
* 获取淘宝商品详情的信息 店铺id 名字 主图 sibUrl 等
*
*
...
@@ -33,7 +39,8 @@ public class JsoupUtil {
...
@@ -33,7 +39,8 @@ public class JsoupUtil {
String
varArr
[]
=
configGroup
.
split
(
";"
);
String
varArr
[]
=
configGroup
.
split
(
";"
);
for
(
String
variable
:
varArr
)
{
for
(
String
variable
:
varArr
)
{
//获取g_config 变量
//获取g_config 变量
Pattern
variablePattern
=
Pattern
.
compile
(
"(g_config){1,1}\\s+={1,1}[\\s\\S]*"
);
// Regex for the value of the key
// Regex for the value of the key
Pattern
variablePattern
=
Pattern
.
compile
(
"(g_config){1,1}\\s+={1,1}[\\s\\S]*"
);
Matcher
varMatcher
=
variablePattern
.
matcher
(
variable
);
Matcher
varMatcher
=
variablePattern
.
matcher
(
variable
);
while
(
varMatcher
.
find
())
{
while
(
varMatcher
.
find
())
{
String
configStr
=
varMatcher
.
group
();
String
configStr
=
varMatcher
.
group
();
...
@@ -225,11 +232,11 @@ public class JsoupUtil {
...
@@ -225,11 +232,11 @@ public class JsoupUtil {
}
}
/**
/**
*
*
获取Zara爬虫的主要数据
* @param content
* @param content
* @return
* @return
*/
*/
public
static
JSONObject
getZara
(
String
content
)
{
public
static
JSONObject
getZara
JsonData
(
String
content
)
{
int
labelHeadIndex
=
content
.
indexOf
(
"dataLayer"
);
int
labelHeadIndex
=
content
.
indexOf
(
"dataLayer"
);
int
labelTailIndex
=
content
.
lastIndexOf
(
";window.zara.viewPayload"
);
int
labelTailIndex
=
content
.
lastIndexOf
(
";window.zara.viewPayload"
);
String
abv
=
content
.
substring
(
labelHeadIndex
,
labelTailIndex
).
replace
(
"dataLayer = "
,
""
);
String
abv
=
content
.
substring
(
labelHeadIndex
,
labelTailIndex
).
replace
(
"dataLayer = "
,
""
);
...
@@ -237,7 +244,6 @@ public class JsoupUtil {
...
@@ -237,7 +244,6 @@ public class JsoupUtil {
return
dataMap
;
return
dataMap
;
}
}
/**
/**
* 根据script id获取内容
* 根据script id获取内容
* @param content
* @param content
...
...
src/main/java/com/diaoyun/zion/master/util/SpiderUtil.java
浏览文件 @
e768cea5
差异被折叠。
点击展开。
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论