林伟强---第二次作业
这个作业属于哪个课程 | 至诚软工实践F班 |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzzcxy/ZhichengSoftengineeringPracticeFclass/homework/12532 |
这个作业的目标 | Java爬虫 抓包解析json并展示数据 |
Gitee 地址 | https://gitee.com/lwq02/rjgc6772 |
***项目准备:IDEA创建springboot
(第一次创建项目可以要导包很久,看网速了)
***项目准备:IDEA连接Gitee
1.Git连接IDEA
- 右键File --> Settings -->Version Control --> Git -->找到安装的git.exe文件(每个人安装的git地址不一样,按自己安装的地址)
2.IDEA连接gitee
- 第一步:安装Gitee插件:打开IDEA --> 右键File --> Settings --> Plugins --> 在中间搜索框中搜索"Gitee" --> 点击 中部有上角的“ Marketplace” --> 点击 "Install" ---> 安装完成后重启idea
- 第二步:IDEA中登录gitee账号:重启IDEA --> 右键File --> Settings -->Version Control --> Gitee(与Git并齐,没有的话说明安装失败)--> 点击 “add account”第一次添加是蓝色的 --> 输入账号(账号为qq邮箱)和密码 --> log In -->添加成功 -->apply --> ok (没有gitee账号的,百度gitee(码云)官网,进出注册账号,然后点设置绑定qq邮箱)
- 第三步:在idea创建码云仓库,将项目托管到码云(不用提前在码云创建仓库)打开IDEA---> 单击菜单的"VCS" --> import into Version Control -->Share Project on Gitee(可能有些布局不一样,反正找到这个gitee点就好了) -->填写本地仓库名(Repository name)和远程仓库名(Remote)和选填描述(Description),最好一致 --> share anyway ---> 登录gitee查看发现推送成功
3.IDEA使用gitee
- 提交到暂存区:IDEA -->右键文件名 --> Git --> Add
- 提交到本地仓库:IDEA -->右键文件名 --> Git --> Commit Directory
- 点击commit提交文件,只选Default Changelist中的文件(其他的不一定要提交)
- 提交到远程仓库:右键项目名文件 --> Git --> Repository --> push
***项目运行
1,在pom.xml导包(三个包)
2,把UtilsparsePuPu.java复制到demo下面(记得改package lwq6772.rjgc.Utils为自己的路径)
3,在***Application启动类添加代码,然后运行main方法
一,爬虫项目解析
1. 项目思路:模拟GET,POST等网络请求爬网站,软件等程序,获取json格式数据并解析 --> 存储 -->展示出来
- 模拟GET,POST等网络请求爬网站,软件等程序
- 可以选择java,python等语言来进行模拟网络请求,python在数据处理方面比较有优势,所以建议使用python来写爬虫程序,不过因为太多人用python,所以我用 java!(java才是最好的编程语言,不同意的话,我只能说啊对对对)
- java项目导入jsoup包,使用jsoup模拟GET,POST等网络请求
- 获取json格式数据的接口
- 可以使用fiddler等抓包工具,抓取json文件接口
- 解析 --> 存储 -->展示出来
- java项目导入gson包,解析json格式
- 使用mysql数据库存储
- 使用echarts+ajax动态获取后端数据并展示出来
2. 具体实施方案
- (1)fiddler抓取json文件接口
- (2)springboot微服务框架的java项目模拟GET,POST等网络请求,请求接口得到返回的json文件解析成数据对象
- (3)将数据对象存到mysql数据库
- (4)前端使用echarts+ajax动态获取后端数据并展示出来
二,爬虫项目实施
项目一: 朴朴商品爬取(Jsoup请求,Gson解析json,控制台输出)
1. fiddler抓取json文件接口
- fiddler抓取的接口:https://j1.pupuapi.com/client/product/storeproduct/detail/7c1208da-907a-4391-9901-35a60096a3f9/b3fc4708-3f1d-412a-8d18-efc4b6951fa7 其中 "store_id":"7c1208da-907a-4391-9901-35a60096a3f9"为商店id;"product_id":"b3fc4708-3f1d-412a-8d18-efc4b6951fa7"为商品id。( 猜测可能是先查询商店id在查询商品id,通过这种方式来减轻数据访问压力。)
2. springboot (网络请求,解析json)
-
UtilsparsePuPu.java爬虫工具类
点击查看pom需要导入的包
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.10.2</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.73</version> </dependency>
点击查看UtilsparsePuPu代码
package lwq6772.rjgc.Utils; import com.google.gson.Gson; import com.google.gson.internal.LinkedTreeMap; import org.jsoup.Connection; import org.jsoup.Jsoup; import java.io.IOException; import java.time.LocalDateTime; import java.util.HashMap; public class UtilsparsePuPu { LinkedTreeMap data ; String name; String spec; Double price; Double market_price; String content; public void parsePuPu() throws IOException { String url="https://j1.pupuapi.com/client/product/storeproduct/detail/831b632e-12bd-4c23-a6fd-a18749d8d508/188d7a73-f518-418e-a928-e293f4b17556"; Connection.Response res = Jsoup.connect(url) .header("Accept", "*/*") .header("Accept-Encoding", "gzip, deflate") .header("Accept-Language","zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3") .header("Content-Type", "application/json;charset=UTF-8") .timeout(10000).ignoreContentType(true).execute(); //创建gson对象 Gson gson = new Gson(); //对获取到的数据进行转换 HashMap hashMap = gson.fromJson(res.body(), HashMap.class); //获取data里面的值 data = (LinkedTreeMap) hashMap.get("data"); /* 获取对应数据 */ name= (String) data.get("name"); spec=(String) data.get("spec"); price=(Double) data.get("price")/100; market_price=(Double) data.get("market_price")/100; content=(String) data.get("share_content"); } public void timing() throws IOException, InterruptedException { //每3秒抓取一次商品信息 while (true){ parsePuPu(); System.out.println("当前时间为"+ LocalDateTime.now()+" ,"+name+":价格为"+price); Thread.sleep(3000); } } public void show() throws InterruptedException, IOException { parsePuPu(); //打印 System.out.println("-----------------------商品:"+name+"-----------------------"); System.out.println("规格:"+spec); System.out.println("价格:"+price); System.out.println("原价/折扣价:"+market_price+"/"+price); System.out.println("详细信息:"+content); System.out.println("--------------------"+name+"的价格波动--------------------"); timing(); } }
-
(1)代码分析
-
网络请求
String url="https://j1.pupuapi.com/client/product/storeproduct/detail/831b632e-12bd-4c23-a6fd-a18749d8d508/188d7a73-f518-418e-a928-e293f4b17556"; Connection.Response res = Jsoup.connect(url) .header("Accept", "*/*") .header("Accept-Encoding", "gzip, deflate") .header("Accept-Language","zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3") .header("Content-Type", "application/json;charset=UTF-8") .timeout(10000).ignoreContentType(true).execute();
-
解析json
//创建gson对象 Gson gson = new Gson(); //对获取到的数据进行转换 HashMap hashMap = gson.fromJson(res.body(), HashMap.class); //获取data里面的值 data = (LinkedTreeMap) hashMap.get("data"); /* 获取对应数据 */ name= (String) data.get("name"); spec=(String) data.get("spec"); price=(Double) data.get("price")/100; market_price=(Double) data.get("market_price")/100; content=(String) data.get("share_content");
-
3. 作业截图
-
具体使用流程点击查询具体使用idea中的gitee插件托管项目这里不赘述
-
commit列表
-
控制台输出
项目二: 知乎收藏夹(Jsoup请求,fastjson解析json,控制台输出)
1. fiddler抓取json文件接口
- 用户收藏夹接口以及返回json格式分析
- fiddler抓取的接口:https://www.zhihu.com/api/v4/people/shuai-qi-66-47/collections 其中用户id:shuai-qi-66-47(这里不想注册知乎,直接用别人的)
- data[{"id":554944525}] 为用户收藏夹id:554944525(这里有个坑!!!,以为id号是长数字,在java中如果使用Gson解析会把长数字转成e+类型的数,无法得到正确id,我的解决方法是使用fastjson来解析)
- data[{"title":"我的收藏夹"}] 为用户收藏夹名
- fiddler抓取的接口:https://www.zhihu.com/api/v4/people/shuai-qi-66-47/collections 其中用户id:shuai-qi-66-47(这里不想注册知乎,直接用别人的)
- 收藏夹下具体收藏文章
- fiddler抓取的接口:https://www.zhihu.com/api/v4/collections/789520124/items?offset=0&limit=20 其中用户收藏夹id:789520124(使用上面获取到的用户收藏夹id)
- 分析json文件
- 上面的收藏夹下的收藏文章的json文件,data中存在多个文章对象,文章对象有两个格式要取出其中的文章标题和url网址
- 第一种文章对象格式data.content.question{"id": 487168564,"title": "Java 的自学神器是什么?","url": "https://www.zhihu.com/question/487168564"} 文章id:{"id":487168564 } 文章标题:{"title": "Java 的自学神器是什么?"} 文章网址url:
- 第二种文章对象格式data.content{"id": "1405971775474155520","title": "15道高频面试题,速通 Java 后端程序员必学知识点!","image_url": "https://pica.zhimg.com/v2-f01dd6dd9e251346d56206e798450af6_r.jpg?source=0df5f383","url": "https://www.zhihu.com/zvideo/1405971775474155520"}文章id:{"id":1405971775474155520} 文章标题:{"title": "15道高频面试题,速通 Java 后端程序员必学知识点!"} 文章网址url:
- fiddler抓取的接口:https://www.zhihu.com/api/v4/collections/789520124/items?offset=0&limit=20 其中用户收藏夹id:789520124(使用上面获取到的用户收藏夹id)
2. java代码(Utilsparse+UtilsparseZhiHu)
-
Utilsparse.java(请求工具类:输入url得到JSONObject对象)
点击查看代码
package lwq6772.rjgc.Utils; import com.alibaba.fastjson.JSONObject; import org.jsoup.Connection; import org.jsoup.Jsoup; import java.io.IOException; public class Utilsparse { static JSONObject Utilget(String url) throws IOException { Connection.Response res = Jsoup.connect(url) .header("Accept", "*/*") .header("Accept-Encoding", "gzip, deflate") .header("Accept-Language","zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3") .header("Content-Type", "application/json;charset=UTF-8") .timeout(10000).ignoreContentType(true).execute(); JSONObject jsonObject = JSONObject.parseObject(res.body()); return jsonObject; } }
-
UtilsparseZhiHu.java(知乎爬虫工具类:调用parseZhiHu方法在控制台输出)
点击查看代码
package lwq6772.rjgc.Utils; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; import com.google.gson.internal.LinkedTreeMap; import org.jsoup.Connection; import org.jsoup.Jsoup; import sun.plugin.util.UserProfile; import java.awt.geom.RoundRectangle2D; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class UtilsparseZhiHu { public void parseZhiHu() throws IOException { JSONObject jsonObject=Utilsparse.Utilget("https://www.zhihu.com/api/v4/people/shuai-qi-66-47/collections"); JSONArray jsonArray = jsonObject.getJSONArray("data"); for (int i = 0; i <jsonArray.size(); i++) { JSONObject jsonArrayObjectItem = JSONObject.parseObject(jsonArray.get(i).toString()); System.out.println(jsonArrayObjectItem.get("title") +" "+jsonArrayObjectItem.get("id")); JSONObject jsonObject1=Utilsparse.Utilget("https://www.zhihu.com/api/v4/collections/"+jsonArrayObjectItem.get("id")+"/items?offset=0&limit=20"); JSONArray jsonArray1 = jsonObject1.getJSONArray("data"); for (int y = 0; y <jsonArray1.size(); y++) { JSONObject jsonArrayObjectItem1 = JSONObject.parseObject(jsonArray1.get(y).toString()); JSONObject jsonObject2= (JSONObject) jsonArrayObjectItem1.get("content"); JSONObject jsonObject3= null; jsonObject3=jsonObject2.getJSONObject("question"); if (jsonObject3==(null)){ System.out.println(jsonObject2.get("title")+" "+jsonObject2.get("url")); }else { System.out.println(jsonObject3.get("title")+" "+jsonObject3.get("url")); } } } } }
3. 作业截图
-
commit列表
-
控制台输出
4. 项目改进,在后续的作业3中将项目分层具体的springboot项目,存入mysql数据库,前端数据展示,上云(卷不动了,看情况更新)
四,知识自学点
- 具体使用流程点击查询具体使用idea中的gitee插件托管项目这里不赘述