注:此篇文章仅供学习使用
由于知乎的内容都是比较精彩和权威,网上很多文章也都是关于爬取知乎内容的,所以笔者也写了一个简单的小爬虫来获取知乎的内容
1. 找到需要爬取的页面
由上诉图片中我们可以得到请求路径,请求方式,浏览器的用户代理,请求参数,响应体等信息
注:由于当前请求是用get方式,部分请求头信息可以忽略
4.准备环境
org.jsoup
jsoup
1.11.3
junit
junit
RELEASE
com.alibaba
fastjson
1.2.50
@Test
public void zh(){
try {
// 封装请求参数
String json = "{\"include\": \"data[*].is_normal,admin_closed_comment,reward_info,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,voteup_count,reshipment_settings,comment_permission,created_time,updated_time,review_info,relevant_info,question,excerpt,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,is_labeled,is_recognized;data[*].mark_infos[*].url;data[*].author.follower_count,badge[*].topics\",\n" +
"\"limit\": 20,\n" + //每列显示的个数
"\"offset\": 15,\n" + //页数
"\"platform\": \"desktop\",\n" +
"\"sort_by\": \"default\"}";
JSONObject object = JSONObject.parseObject(json);
// 使用jsoup对url参数发起请求
Connection connect = Jsoup.connect("https://www.zhihu.com/api/v4/questions/22913650/answers");
// 将封装的参数放至jsoup 作为发送请求的参数 例:?limit: 20&offset: 15
for (String key : object.keySet()) {
connect.data(key,object.get(key).toString());
}
// 发起请求并接受响应
Connection.Response response = connect
// 防止 UnsupportedMimeTypeException 异常
.ignoreContentType(true)
// 伪装
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36")
.execute();
// 解析响应体
JSONObject responseJson = JSONObject.parseObject(response.body());
JSONArray dataArray = JSONArray.parseArray(responseJson.get("data").toString());
/**
* 文件io操作
*/
// 创建 C:\Users\Admin\Desktop 文件夹
File file = new File("C:\\Users\\Admin\\Desktop");
if (!file.exists()) {
file.mkdirs();
}
// 创建 C:\Users\Admin\Desktop\zh.txt 文件
File ZH = new File("C:\\Users\\Admin\\Desktop\\zh.txt");
if (!ZH.isFile()){
ZH.createNewFile();
}
// 文件输出流&高效输出流 用于将数据写入到指定文件中
FileWriter fileWriter = new FileWriter(ZH,true);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
// 从返回的响应体中过滤想要的数据并写入到文件中
for (Object data : dataArray) {
JSONObject dataJO = JSONObject.parseObject(data.toString());
JSONObject author = JSONObject.parseObject(dataJO.get("author").toString());
Object authorName = author.get("name");
Object excerpt = dataJO.get("content");
Object voteup_count = dataJO.get("voteup_count");
// 将数据写入缓存区
bufferedWriter.write(authorName+"("+voteup_count+"人赞同):");
bufferedWriter.write("\n");
bufferedWriter.write(excerpt.toString());
bufferedWriter.write("\n");
bufferedWriter.write("\n");
bufferedWriter.write("\n");
}
// 刷新 注:将缓存区的数据刷新到文件中
bufferedWriter.flush();
// 关流 注:节约资源
fileWriter.close();
bufferedWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
返回结果:
上诉代码可以封装为一个方法,有兴趣可以自行封装
{\__/} {\__/}
( ·-·) (·-· )
/ >------------------------------------------------< \
| ☆ |
| ☆ |
| ★ |
| ☆ |
| ☆ |
| |
-------------------------------------