黄鸿斌---第二次作业
这个作业属于哪个课程 | 至诚软工实践F班 |
---|---|
这个作业要求在哪里 | 作业要求的链接 |
这个作业的目标 | 在完成作业的过程中学习到知识 |
学号 | 212106714 |
Github项目地址:java-web-learning
1.1 解题思路描述
- 刚开始拿到题目后,我给自己提出了三个问题
- 己会的(java)基础上进行解题
- 是提供Fillder提供的api解题
- 还是Fiddler爬完后的数据存在本地,在利用java的IO流进行分析。
由于我之前没有接触过爬虫和Fiddler这个软件,所以以上三个解题思路上饶了两三天。
当我听到同学用python爬虫时,我就想java是不是也能实现类似的爬虫,于是我便跳出思维圈,在b站开始搜索java爬虫的内容进行学习。
1.2 设计实现过程
-
在项目开始之前,我们需要简单的了解两个知识
- 客户端渲染 :请求某个页面,告诉你一个html,里面是空的,然后会加载一个js,js去请求,得到数据后,才把这个页面填充完整。
- 服务端的渲染 :一次性就告诉了你所有内容。
- 客户端渲染 :请求某个页面,告诉你一个html,里面是空的,然后会加载一个js,js去请求,得到数据后,才把这个页面填充完整。
-
我们这次的任务时通过fiddler抓取朴朴的页面地址。
但朴朴是客户端渲染(微信小程序也是),
也就是说我们可能会利用到无头浏览器来让客户端实现js,再获取页面。 -
但我们在fiddler中抓取到的url显示,它是一个接口,返回的是json文件
所以我们就可以简单的将接口数据进行获取,解析,在构成对象,进而获取数据.
1.2.1 当前项目使用的依赖(jar包)导入maven
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
1.2.2 商品类
- 我们就需要拥有一个商品类来装载我们需要的信息
- 按照pojo规范制作一个简单的java对象
classDiagram
class Product{
Product : - String name ----------------商品名字
Product : - float price ------------------商品价格
Product : - float market_price --------商品原价
Product : - String spec -----------------商品规格
Product : - Stringshare_content -------商品内容
}
1.2.3 httpClient管理器
- 我们继续设置个httpClient管理器,来根据接口提供的json数据
- 继续按照pojo规范制作一个简单的java对象
classDiagram
class HttpClientController{
- String url ----------------接口地址
+ doGet()
}
1.2.3 启动器
- 它提供了主要的main方法以及多个处理数据的方法
classDiagram
class HttpGetTest{
+ main()
+ showProductInfo(商品对象)
+ estaProduct(JSON数据对象)
+ currentPrice(httpclient管理器)
}
- 以上具体主要实现过程在 代码说明 中
1.3 代码说明
1.3.1 httpclient的主要方法:
- 根据链接获取json数据信息 创建json对象并返回
点击查看详情
/** * 创建链接获取json数据信息 * @return json数据对象 */ public JSONObject doGet() { //设置httpclient CloseableHttpClient httpClient = HttpClients.createDefault(); //创建请求 HttpGet httpGet = new HttpGet(url); //创建响应容器 CloseableHttpResponse response = null; try { //执行请求,获取响应数据 response = httpClient.execute(httpGet); //当状态代码为200时,则表面获取成功 if (response.getStatusLine().getStatusCode() == 200) { //获取响应信息实体 HttpEntity entity = response.getEntity(); //利用工具将实体信息转换为字符串 String JsonData = EntityUtils.toString(entity); //利用fastjson将字符串信息(json信息)转换为对象 JSONObject tempObject = JSONObject.parseObject(JsonData); //返回json信息对象 return tempObject; } } catch (IOException e) { e.printStackTrace(); } finally { try { //关闭链接 httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } return null; }
- 思路:
- 以默认设置创建一个httpclient,再通过httpGet连接创建请求.
- http客户端执行请求,并获取响应
- 判断响应是否异常
- 获取信息实体并将其转换为json数据对象返回
1.3.2 HttpGetTest的主要方法:
- 处理各个数据,并展示
点击查看详情
/** * 商品信息显示 * @param product 商品对象 */ public void showProductInfo(Product product){ System.out.println("-----------商品:" + product.getName() + "------------------"); System.out.println("规格:" + product.getSpec()); System.out.println("价格:" + product.getPrice()); System.out.println("原价/折扣价:" + product.getMarket_price()+ "/" + product.getPrice()); System.out.println("详细内容:" + product.getShare_content()); System.out.println("-----------\""+product.getName()+"\" 的价格波动--------------------"); } /** * 建立商品对象 * @param jsonObject json信息 * @return 商品对象 */ public Product estaProduct(JSONObject jsonObject) { //获取信息数据 String data = jsonObject.getString("data"); //建立商品对象 Product product = JSONObject.parseObject(data, Product.class); //返回商品对象 return product; } /** * 查询当前时间价格 * @param httpCC httpclient控制器 */ public void currentPrice(HttpClientController httpCC){ //获得json数据对象 JSONObject object = httpCC.doGet(); //建立商品对象 Product product = estaProduct(object); //获取当前时间 LocalDateTime now = LocalDateTime.now(); //设置转换后的格式 String strPattern="yyyy年MM月dd日 HH点mm分ss秒"; //赋予时间转换器转换格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(strPattern); //转换时间 String timeOfZHCN = formatter.format(now); //输出 System.out.println("当前时间为"+timeOfZHCN+",价格为"+product.getPrice()); }
- 思路:
- showProductInfo 方法负责将传入的商品对象,获取其数据,输出至控制台
- estaProduct 方法负责根据json数据对象建立商品对象
- currentPrice 方法负责输出实时价格,调用doGet以及estaProduct方法。该方法供计时任务使用
1.3.2 main方法实现
- 将各个类的方法进行利用,实现作业效果
点击查看详情
public static void main(String[] args){ //设置url地址 String url ="https://j1.pupuapi.com/client/product/storeproduct/detail/7c1208da-907a-4391-9901-35a60096a3f9/f883cc75-7597-4c7a-a420-6ce5aa7fe2ed"; //创建httpclient控制器 HttpClientController httpCC = new HttpClientController(url); //创建信息处理器 HttpGetTest httpGetTest = new HttpGetTest(); //获得商品的json信息 JSONObject object = httpCC.doGet(); //利用json数据创建商品对象 Product product = httpGetTest.estaProduct(object); //显示商品信息 httpGetTest.showProductInfo(product); //设置时间任务,每隔5s时间执行查询价格的方法(5000ms<->5s) Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { httpGetTest.currentPrice(httpCC); } },1000,5000); }
- 思路:
- 将Fiddler抓取的数据赋给url变量
- 创建控制器以及信息处理器,利用其创造对象,输出信息
- 创建定时任务,定时执行获取价格的方法
1.4 代码运行效果展示
- 运行结果
- github commit次数
- idea git的使用
总结
这次作业虽然制作了第一题,在Java的基础上完成作业,而不是Python。但在学习的过程中了解到了许多javaweb的知识,我也向朋友了解到网页渲染的机制,以及后端向前端的对接相关知识。可以说拓展了我的知识面。
作业的话,对于第二题,实际上我已经通过对知乎收藏夹的分析,了解到了他的内容实际上是由前端js向后端请求到的json数据在渲染出来的,而且我也抓住了它的接口,我完全可以使用第一题一模一样的方式进行分析,转换对象,在输出。
但我选择了换一种思路去做,利用seleuim和webmagic实现无头浏览器。对网页进行渲染后再转换成普通html格式的document,再利用jsoup对标签,类以及id进行分析,获取内容。目前还在学习相关知识中,我觉得利用这种方式看起来可能更由逻辑性,层次性。
目前已实现对收藏夹名字,收藏夹网页链接的获取,正尝试获取内容标题和链接。
缺点是有点南辕北辙的味道。