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

动态ajax页面为什么会再同一个页面有多个分页,就是因为当你点击其他页的时候服务器返回一串json串,js执行json参数达到改变页面效果。下面说说如何抓取json串。
1:爬取信息要对源页有所了解,首先打开虎牙直播,谷歌F12选取network。点xhr。里面可能会有多个json文件,点击第三页。
这里写图片描述
发现点击第三页后会出现一个新的json串。点击看下
这里写图片描述
会发现服务器返回的数据就是这个页面所显示的。你想要的数据都在里面。可以通过这个数据爬取有用的信息。查看服务器的请求
这里写图片描述
最下面一行的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<String, String> header = new HashMap<String, String>();     
          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());
    }
}

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

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();
}
}

有一点比较重要的是解析json时一定要使用try catch别用再主函数抛出异常,因为各种原因可能服务器会返回错误的一个或者json串,而多组数据如果不用try catch的话会异常终止,使用后会直接跳过去,这种情况虽然少但是还是会发生。所以大不了就跳过一页中间数据。这样,数据就存在数据库里了。
这里写图片描述
初学者。可能代码有很多不好的地方。多多见谅

猜你喜欢

转载自blog.csdn.net/qq_40693171/article/details/80094825