前言
这几天打算考一个`1+X 大数据应用中级证书`,这个是蓝桥的,我和蓝桥挺有缘的。高中就听过蓝桥杯,大一也如愿参加了现在又是蓝桥的这个证书。
做了一下官方的模拟考试,发现考的并不是特别难,但是相应的技术都已经学过了,所以想利用这些知识来实战一下。
技术点有:网络请求、mysql存储数据、JSON数据解析
爬取目标:蓝桥杯大赛的所有大赛通知
32页数据 ,将每条的标题\内容\发布日期\存储到数据库中
通过浏览器的开发者工具抓了下包,配合Postman调试了一下
得到以下的信息:
METHOD:POST
BODY:
参数名 | 示例 |
---|---|
url | http://10.251.196.135/API.php?m=list&id=20&p=1&s=10 |
其中 p 代表页码,s 代表每一页的数据条数。
理论上可以一个请求获取到所有的数据,在明确数据总条数的情况
但是本篇讲解是基于不断改变页码的方式来操作的,有兴趣可以自主尝试一下前者
二、编码
MAVEN配置
<dependencies> <!-- 网络请求 所需要的包 --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.6</version> </dependency> <!-- 引入fastjson 解析json数据--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <!-- 含有转义与去除转义的功能 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-text</artifactId> <version>1.1</version> </dependency> <!-- MySql 8.0.18 Connector --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.18</version> </dependency> </dependencies>
代码
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
/**
* @author hygge
* @description
* @create 2020/12/25 20:10
*/
public class main {
public static void main(String[] args) {
//初始化网络请求的对象
CloseableHttpClient client = HttpClients.createDefault();
//定义网络响应对象
CloseableHttpResponse response = null;
//定义请求方式
HttpPost httpPost = new HttpPost("https://dasai.lanqiao.cn/api/action/http/get");
NameValuePair para = new BasicNameValuePair("url","http://10.251.196.135/API.php?m=list&id=20&p=1&s=10");
List<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(para);
try {
StringEntity stringEntity = new UrlEncodedFormEntity(list);
httpPost.setEntity(stringEntity);
//client.execute()会导致IOException 异常,所以要捕捉一下
//execute()需要一个实现HttpUriRequest接口的类作为参数,有HttpPost\HttpGet,详见该接口的源码
response = client.execute(httpPost);
// 对响应的状态码进行判断。
if(response.getStatusLine().getStatusCode() == 200){
//获取响应的源代码
HttpEntity entity = response.getEntity();
String str = EntityUtils.toString(entity, "UTF-8");
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
// 防止响应为空
if(response != null){
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 防止请求为空
if(client != null){
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行查看效果
控制台中可以看到打印的响应
下面要做两件事,
去除响应的转义,也就是 \" 等字符
去除开头和结尾的引号
应字符串解析为JSON数据
// StringEscapeUtils 来自于 依赖中的 commons-text
str = StringEscapeUtils.unescapeJava(str);
str = str.substring(1,str.length() - 1);
//打印一下 发现去除转义、开头结尾的引号的效果已经达到。
//{"total":"315","new_list":[{"id":"1850","title":"……
将响应格式化一下:
发现响应本身是一个jsonObject
,我们要的是 new_list
节点,它是一个jsonArray
,照此思路我们来解析它。
//将响应字符串 先 转为 JSONObject
JSONObject allObj = JSON.parseObject(str);
//取出其中的new_list节点 作为JSONArray
JSONArray new_list = allObj.getJSONArray("new_list");
//我们来遍历一下这个JSONArray
JSONObject item = null;
for(int i = 0;i < new_list.size();i++){
item = new_list.getJSONObject(i);
System.out.println(item.getString("title"));
System.out.println(item.getString("content"));
System.out.println(item.getString("up_time"));
}
完成
好文章!