动态ajax页面为什么会再同一个页面有多个分页,就是因为当你点击其他页的时候服务器返回一串json串,js执行json参数达到改变页面效果。下面说说如何抓取json串。

1:爬取信息要对源页有所了解,首先打开虎牙直播,谷歌F12选取network。点xhr。里面可能会有多个json文件,点击第三页。

爬取虎牙之三:通过json数据获取所有直播情况_json


发现点击第三页后会出现一个新的json串。点击看下

爬取虎牙之三:通过json数据获取所有直播情况_sql_02


会发现服务器返回的数据就是这个页面所显示的。你想要的数据都在里面。可以通过这个数据爬取有用的信息。查看服务器的请求

爬取虎牙之三:通过json数据获取所有直播情况_sql_03


最下面一行的Query String Parameters就是需要的请求,这样我们模拟请求就可以获取信息。

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

public class test2 {
public static void main(String[] args) throws IOException
{
String url="https://www.huya.com/";
Connection connect = Jsoup.connect(url).timeout(20000);
Map header = new HashMap();
header.put("m", "LiveList");
header.put("do", "getLiveListByPage");
header.put("tagAll", "0");
header.put("page", "3");
connect.data(header);
Document doc=connect.get();
System.out.println(doc.text());
}
}

却发现输出的是

爬取虎牙之三:通过json数据获取所有直播情况_json_04


这个就是前面xhr中的response文件。并且这是一个json串,要想转换json变成我们想要的东西。就要使用阿里的fastjson解析工具,导入fastjson包就可以使用。对于fastjson的简单使用,可以先简单对单个数据摸索。尝试看看。就可以获得想要的数据。json串的解析和获取信息需要自己慢慢摸索。贴上最终的代码:

package 虎牙斗鱼直播平台;

import java.io.IOException;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/*
* 直接抓所有直播
*/
public class 抓取所有主播 {
public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException {
int id = 1;
/*
* 连接数据库
*/
java.sql.Connection con;
Class.forName("com.mysql.jdbc.Driver");
System.out.println("数据库驱动加载成功");
con = DriverManager.getConnection("jdbc:mysql:" + "//127.0.0.1:3306/db?useSSL=true", "root", "123456");
System.out.println("数据库连接成功");
/*
* 模拟请求 注意,请求的页面不同
*/
String url = "https://www.huya.com/";
Connection connect = Jsoup.connect(url).timeout(20000);
Map<String, String> header = new HashMap<String, String>();
header.put("m", "LiveList");
header.put("do", "getLiveListByPage");
header.put("tagAll", "0");
int page = 0;// 页数

// 获取页面数操作 首先要用jsoup解析当前页面,看看有多少页,
Document exam = Jsoup.connect("https://www.huya.com/l").get();// 请求链接所有直播
Elements links = exam.getElementsByClass("list-page");// 可以遍历到人数和主播昵称
page = Integer.parseInt(links.attr("data-pages"));
System.out.println(page);
for (int i = 0; i < page; i++) {
header.put("page", 1 + i + "");
Connection data = connect.data(header);
Document doc = data.get(); // 获取json字符串
// System.out.println(doc.text());
try {
JSONObject jsonObj = JSON.parseObject(doc.text()); // 将json字符串转成中文 获得主要的json串
// System.out.println(jsonObj);

JSONObject jsonOb = JSON.parseObject(jsonObj.getString("data"));// 获取data选项的json内容
// System.out.println(jsonOb);
JSONArray jarr = jsonOb.getJSONArray("datas");// 获取datas内容的jsonarray可以看作是多组jsonobjiect组成
for (Object jar : jarr) {
JSONObject js = JSON.parseObject(jar.toString());// 获取更具体的json值
/*
* 写入数据库
*/
int renshu = Integer.parseInt((String) js.get("totalCount"));
String type = js.get("gameFullName").toString();
String sql2 = "insert into satuday(name,href,number,type)value(?,?,?,?)";// 插入mysql姓名 链接 观看人数 分类

PreparedStatement pstmt = con.prepareStatement(sql2);
pstmt.setString(1, (String) js.get("nick")); // 可以查看json数据preview里面的选项做参考
pstmt.setString(2, "https://www.huya.com/" + js.get("profileRoom"));
pstmt.setInt(3, renshu);
pstmt.setString(4, type);
pstmt.execute();
System.out.println(js.get("gameFullName") + "" + id++ + " " + i + "");
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
con.close();
}
}
  • 如果对爬虫,数据结构,java感兴趣可以关注笔者公众号:​​bigsai​