提交 6bcf9a53 authored 作者: 梁业锦's avatar 梁业锦 💬

已修复优衣库与MD在手机页面无法显示的问题

上级 af3eb65a
...@@ -21,34 +21,63 @@ ...@@ -21,34 +21,63 @@
> 注意爬虫的命名 > 注意爬虫的命名
## 需要爬取的购物网站 # 爬虫步骤
### Pull and Bear ## 目的
帮助不能使用国内购物平台的用户进行**代购服务**,而要进行代购,就要**帮助他们下单**。为了帮助用户下单,很重要的
一步就是要**获取平台的商品的规格**;让用户可以在浏览的时候,可以让他们在我们app上选择相应规格的商品
## 分析页面数据
首先要明白的是:App页面传给我们的只有原始商品的连接,为了获取页面上的商品信息有两种方式:
- 分析**页面**构成,例如:Zara 爬虫
- 在某个地方会存在json数据的传递
- 嵌套在Html页面中的各种数据
- 分析页面调用接口后的返回数据,例如:Uniqlo 优衣库爬虫
## 页面中存在Json数据传递的--示例:Zara
### 1.随便点击一个商品详情页<br>
![](img/zara商品页.png)
### 2.通过商品的一些关键信息进行搜索<br>
![](img/zara关键子搜索.png)
### 3.检索信息(关键步骤)
- (1) **感觉可能**这是相关的商品详情信息,而且是**Json格式**的数据
- (2) 通过[Json格式化工具:http://www.bejson.com/jsonviewernew/](http://www.bejson.com/jsonviewernew/)来格式化Json数据
- (3) 再次通过关键搜索诸如**价格****尺寸**等,检查数据是否是我们想要的、是否是完整的,如果不是重复(1)、(2)步骤继续搜寻<br>
![](img/zara截取的数据.png)
- (4) 确认完数据后查看该 json 的id名是什么<br>
- Zara传递的这个Json的id是**dataLayer**<br>
![](img/Zara爬虫05.png)
### 4.截取数据封装数据
- 新键该爬虫,请看**添加新爬虫至项目规范**
- [ZaraSpider.java](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/ZaraSpider.java)
- 如何处理数据详情请看爬虫的@see注释
# 需要爬取的购物网站
### [Pull and Bear](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/PullandbearSpider.java)
- 主页:https://www.pullandbear.cn/cn/%E5%A5%B3%E5%A3%AB-c1030204574.html - 主页:https://www.pullandbear.cn/cn/%E5%A5%B3%E5%A3%AB-c1030204574.html
- 命名:pullandbear - 命名:pullandbear
- 爬虫进度:**已完成** - 爬虫进度:**已完成**
- 有反爬机制,有时会直接失效,不稳定 - 有反爬机制,有时会直接失效,不稳定
### Gap ### [Gap](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/GapItemSpider.java)
- 主页:https://www.gap.cn/ - 主页:https://www.gap.cn/
- 命名:gap - 命名:gap
- 爬虫进度:**已完成** - 爬虫进度:**已完成**
### Zara ### [Zara](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/ZaraSpider.java)
- 主页:https://www.zara.cn/cn - 主页:https://www.zara.cn/cn
- 命名:zara - 命名:zara
- 爬虫进度:**已完成** - 爬虫进度:**已完成**
### Uniqlo ### [Uniqlo](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/UniqloSpider.java)
- 主页:https://www.uniqlo.cn/UNIQLO_U19FW_MEN.html - 主页:https://www.uniqlo.cn/UNIQLO_U19FW_MEN.html
- 命名:uniqlo - 命名:uniqlo
- 爬虫进度:**已完成** - 爬虫进度:**已完成**
- 可能存在的缺陷: - 可能存在的缺陷:
- 图片的路径是直接下载图片 - 图片的路径是直接下载图片
### Nike ### [Nike](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/NikeItemSpider.java)
- 主页:https://www.nike.com/cn - 主页:https://www.nike.com/cn
- 命名:nike - 命名:nike
- 爬虫进度:**已完成** - 爬虫进度:**已完成**
### Adidas ### Adidas
- 主页:https://www.adidas.com.cn/ - 主页:https://www.adidas.com.cn/
- 命名:adidas - 命名:adidas
- 爬虫进度: - 爬虫进度:数据嵌在HTML中
### H&M ### H&M
- 主页:https://www2.hm.com/zh_cn/ - 主页:https://www2.hm.com/zh_cn/
- 命名:hm - 命名:hm
...@@ -58,7 +87,7 @@ ...@@ -58,7 +87,7 @@
### LiLy ### LiLy
- 主页:http://www.lily.sh.cn/webapp/wcs/stores/servlet/lilystore - 主页:http://www.lily.sh.cn/webapp/wcs/stores/servlet/lilystore
- 命名:lily - 命名:lily
- 爬虫进度: - 爬虫进度:数据嵌在HTML中
### Eifini ### Eifini
- 主页:https://eifini.tmall.com/ - 主页:https://eifini.tmall.com/
- 命名:eifini - 命名:eifini
...@@ -95,7 +124,7 @@ ...@@ -95,7 +124,7 @@
- 主页:https://www.moco.com/moco/zh/c/BS_DISCOUNT - 主页:https://www.moco.com/moco/zh/c/BS_DISCOUNT
- 命名:moco - 命名:moco
- 爬虫进度: - 爬虫进度:
### Massimo Dutti ### [Massimo Dutti](../src/main/java/com/diaoyun/zion/chinafrica/bis/impl/MassimoduttiSpider.java)
- 主页:https://www.massimodutti.cn/cn/男装/季末折扣/休闲西装-c1745921.html - 主页:https://www.massimodutti.cn/cn/男装/季末折扣/休闲西装-c1745921.html
- 命名:massimodutti - 命名:massimodutti
- 爬虫进度:**已完成** - 爬虫进度:**已完成**
...@@ -132,17 +161,15 @@ ...@@ -132,17 +161,15 @@
- 32,https://www.apple.com/cn/shop/buy-iphone/iphone-xr - 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 - 33,https://www.louisvuitton.cn/zhs-cn/homepage?campaign=sem_CN_ZHS_BA_EC_BZON_PC_Valuable_H1_homepage
# 爬虫Json数据返回规范
## 封装类 [ProductResponse](../src/main/java/com/diaoyun/zion/chinafrica/vo/ProductResponse.java)
## 爬虫Json数据返回规范
### 封装类 [ProductResponse](../src/main/java/com/diaoyun/zion/chinafrica/vo/ProductResponse.java)
封装类的属性已经说明了爬虫需要爬取的数据有哪一些 封装类的属性已经说明了爬虫需要爬取的数据有哪一些
- skuId 标识规范:;[颜色id];[尺寸id]; - skuId 标识规范:;[颜色id];[尺寸id];
- 该 id 通过爬取**颜色****尺寸**对应数据时获取到的唯一标识 - 该 id 通过爬取**颜色****尺寸**对应数据时获取到的唯一标识
- 用于标识**库存****价格** - 用于标识**库存****价格**
#### 按照 Nike 爬虫返回的数据进行封装 ### 按照 Nike 爬虫返回的数据进行封装
│── data 数据<br> │── data 数据<br>
│ │── dynStock 库存<br> │ │── dynStock 库存<br>
│ ││─── productSkuStockList 库存数量的集合<br> │ ││─── productSkuStockList 库存数量的集合<br>
...@@ -174,7 +201,7 @@ ...@@ -174,7 +201,7 @@
│── code 1 <br> │── code 1 <br>
│── message "商品规格信息" <br> │── message "商品规格信息" <br>
#### Nike 返回的 json 数据示范
```json ```json
{ {
"data": { "data": {
......
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.SpiderUtil;
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;
/**
* Adidas 数据爬虫
*
* @author 爱酱油不爱醋
*/
@Component("adidasSpider")
public class AdidasSpider implements IItemSpider {
private static Logger logger = LoggerFactory.getLogger(PullandbearSpider.class);
/**
* Adidas 商品详情页连接
*/
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 格式化数据方法
* @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据
*/
@Override
public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException {
JSONObject resultJson = JSONObject.fromObject(targetUrl);
return resultJson;
}
public static void main(String[] args) throws Exception {
String targetUrl = "";
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.ADIDAS.getValue());
System.out.println(content);
}
}
...@@ -24,9 +24,16 @@ import java.util.concurrent.TimeoutException; ...@@ -24,9 +24,16 @@ import java.util.concurrent.TimeoutException;
public class HmSpider implements IItemSpider { public class HmSpider implements IItemSpider {
private static Logger logger = LoggerFactory.getLogger(UniqloSpider.class); private static Logger logger = LoggerFactory.getLogger(UniqloSpider.class);
// H&M 详情商品页url /**
private static final String uniqloUrl = ""; * H&M 详情商品页url
*/
private static final String H_M_URL = "https://www2.hm.com/zh_cn/productpage";
/**
* H&M 数据格式化
* @param targetUrl
* @return
*/
@Override @Override
public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException { public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException {
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.HM.getValue()); String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.HM.getValue());
......
...@@ -20,6 +20,9 @@ import java.util.concurrent.TimeoutException; ...@@ -20,6 +20,9 @@ import java.util.concurrent.TimeoutException;
/** /**
* Massimo Dutti 数据爬虫 * 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
*
* @author 爱酱油不爱醋 * @author 爱酱油不爱醋
*/ */
@Component("massimoduttiSpider") @Component("massimoduttiSpider")
......
...@@ -34,7 +34,6 @@ public class UniqloSpider implements IItemSpider { ...@@ -34,7 +34,6 @@ public class UniqloSpider implements IItemSpider {
/** /**
* Uniqlo 数据爬虫 * Uniqlo 数据爬虫
* @see com.diaoyun.zion.chinafrica.service.impl.SpiderServiceImpl#judgeUrlType 修改商品详情页路径 * @see com.diaoyun.zion.chinafrica.service.impl.SpiderServiceImpl#judgeUrlType 修改商品详情页路径
* @see
* @see SpiderUtil#formatUniqloProductResponse 格式化数据方法 * @see SpiderUtil#formatUniqloProductResponse 格式化数据方法
* @param targetUrl 接收的商品详情路径 * @param targetUrl 接收的商品详情路径
* @return 格式化与翻译后的 Json 数据 * @return 格式化与翻译后的 Json 数据
...@@ -42,7 +41,7 @@ public class UniqloSpider implements IItemSpider { ...@@ -42,7 +41,7 @@ public class UniqloSpider implements IItemSpider {
@Override @Override
public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException { public JSONObject captureItem(String targetUrl) throws URISyntaxException, IOException, ExecutionException, InterruptedException, TimeoutException {
// 截取链接中的商品 id // 截取链接中的商品 id
String[] split = targetUrl.split("productCode="); String[] split = targetUrl.split("pid=");
String pId = split[1]; String pId = split[1];
targetUrl = UNIQLO_URL + "zh_CN/" + pId + ".json"; targetUrl = UNIQLO_URL + "zh_CN/" + pId + ".json";
String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.UNIQLO.getValue()); String content = HttpClientUtil.getContentByUrl(targetUrl, PlatformEnum.UNIQLO.getValue());
......
...@@ -30,7 +30,7 @@ public class ZaraSpider implements IItemSpider { ...@@ -30,7 +30,7 @@ public class ZaraSpider implements IItemSpider {
private static Logger logger = LoggerFactory.getLogger(ZaraSpider.class); private static Logger logger = LoggerFactory.getLogger(ZaraSpider.class);
/** /**
* Zara 商品详情页Url * Massimo Dutti 商品详情页Url
*/ */
private static final String ZARA_URL = "https://www.zara.cn/cn/zh/"; private static final String ZARA_URL = "https://www.zara.cn/cn/zh/";
......
...@@ -17,6 +17,7 @@ public enum PlatformEnum implements EnumItemable<PlatformEnum> { ...@@ -17,6 +17,7 @@ public enum PlatformEnum implements EnumItemable<PlatformEnum> {
ZARA("Zara", "zara"), ZARA("Zara", "zara"),
UNIQLO("优衣库", "uniqlo"), UNIQLO("优衣库", "uniqlo"),
NIKE("NIKE", "nike"), NIKE("NIKE", "nike"),
ADIDAS("Adidas", "adidas"),
HM("H&M", "hm"), HM("H&M", "hm"),
MASSIMODUTTI("MassimoDutti", "massimodutti"), MASSIMODUTTI("MassimoDutti", "massimodutti"),
UN("未知", "un"), UN("未知", "un"),
......
...@@ -40,6 +40,10 @@ public class ItemSpiderFactory { ...@@ -40,6 +40,10 @@ public class ItemSpiderFactory {
iItemSpider= (IItemSpider) SpringContextUtil.getBean("nikeItemSpider"); iItemSpider= (IItemSpider) SpringContextUtil.getBean("nikeItemSpider");
break; break;
} }
case "adidas":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("adidasSpider");
break;
}
case "hm":{ case "hm":{
iItemSpider= (IItemSpider) SpringContextUtil.getBean("hmSpider"); iItemSpider= (IItemSpider) SpringContextUtil.getBean("hmSpider");
break; break;
......
...@@ -53,15 +53,17 @@ public class SpiderServiceImpl implements SpiderService { ...@@ -53,15 +53,17 @@ public class SpiderServiceImpl implements SpiderService {
platformEnum=PlatformEnum.GAP; platformEnum=PlatformEnum.GAP;
} else if(targetUrl.contains("www.nike.com/cn/t/")) { } else if(targetUrl.contains("www.nike.com/cn/t/")) {
platformEnum=PlatformEnum.NIKE; 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/")) { } else if(targetUrl.contains("www.afri-eshop.com")&&targetUrl.contains("/products/")) {
platformEnum=PlatformEnum.AfriEshop; platformEnum=PlatformEnum.AfriEshop;
} else if (targetUrl.contains("zara.cn")) { } else if (targetUrl.contains("zara.cn")) {
platformEnum = PlatformEnum.ZARA; platformEnum = PlatformEnum.ZARA;
} else if (targetUrl.contains("uniqlo.cn/product-detail.html")) { } else if (targetUrl.contains("h.uniqlo.cn/#/product")) {
platformEnum = PlatformEnum.UNIQLO; platformEnum = PlatformEnum.UNIQLO;
} else if (targetUrl.contains("hm.com/zh_cn/productpage")) { } else if (targetUrl.contains("hm.com/zh_cn/productpage")) {
platformEnum = PlatformEnum.HM; platformEnum = PlatformEnum.HM;
} else if (targetUrl.contains("massimodutti.cn/")) { } else if (targetUrl.contains("massimodutti.cn/") && targetUrl.contains("colorId") && targetUrl.contains("categoryId")) {
platformEnum = PlatformEnum.MASSIMODUTTI; platformEnum = PlatformEnum.MASSIMODUTTI;
} }
return platformEnum; return platformEnum;
......
...@@ -39,11 +39,11 @@ spring: ...@@ -39,11 +39,11 @@ spring:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/chinafrica?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8 # url: jdbc:mysql://localhost:3306/chinafrica?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
# username: root # username: root
# password: 1234 # password: root
#测试环境 #测试环境
url: jdbc:mysql://localhost:3306/chinafrica?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&useSSL=false url: jdbc:mysql://47.106.242.175:3306/chinafrica?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&useSSL=false
username: root username: root
password: root password: diaoyun666
# 连接池配置 # 连接池配置
initial-size: 5 initial-size: 5
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论