【java】使用jsonp请求并解析网页元素内容,爬取网站热点数据

org.jsonp这个包里的类可以用来对网页请求,然后获取请求返回的网页或者是json字符串。

Document doc = null;  
Connection connection = Jsoup.connect(url);  
connection.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");  
connection.header("Accept-Encoding", "gzip, deflate, br");  
connection.header("Accept-Language", "en-US,en;q=0.5");  
connection.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0");
if (headers != null)  
{  
    connection.headers(headers);  
}  
try  
{  
    doc = connection.timeout(10 * 1000).get();  
}  
catch (IOException e)  
{  
    log.error("Fail to connect!", e);  
}  
return doc;

如果网页返回的为json字符串:

String json = null;
try
{
    json = Jsoup.connect(url).ignoreContentType(true).execute().body();
}
catch (IOException e)
{
    log.error("Fail to connect the website!", e);
}
return json;

import com.jayway.jsonpath.JsonPath;
List<String> titles = JsonPath.read(jsonStr, "$.rankList.[*].title");

使用该JsonPath工具类可以读取json字符串
如上的使用方法为读取jsonStr该json字符串下的,rankList数组里所有元素的title值,然后放到一个list里面。


实例演示

获取ACFUN的排行榜视频标题以及链接,放到一个列表里去:

首先去acfun官网排行榜页面找获取排行榜数据的请求,
YQvTYT.png
得知该请求方式返回一个很长的json数据。
复制下来使用notepad++格式化后可以看到这样的数据层次:

{
    "result": 0,
    "host-name": "hb2-acfun-kcs085.aliyun",
    "rankList": [
        {
            "groupId": "Ml8wXzE1ODkwMTEyMjQ0NTVfNTY_1",
            "userId": 233486,
            "dougaId": "15402363",
            "channelId": 86,
            "videoCover": "https://tx-free-imgs.acfun.cn/content/2020_05_08/1588922111122.JPG?imageslim",
            "userImg": "https://tx-free-imgs.acfun.cn/style/image/201907/tXEU6GKinPO0cygwHbmOU7DAsfw1iPvU.jpg?imageslim",
            "fansCount": 15747,
            "channelName": "生活日常",
            "contentId": 15402363,
            "isFollowing": false,
            "contributionCount": 50,
            "danmuCount": 993,
            "contentTitle": "MC石头:成年人的悲哀",
            "contentDesc": "生活中总有那么一些成年后的烦恼,慢慢的就习惯了。Vx:mcfanjian QQ:337845818",
            "userSignature": "Vx号mcfanjian,扣扣337845818,粉丝q群138836999,网易云:MC石头",
            "contributeTime": 1588924233279,
            "userName": "MC石头",
            "contentType": 2,
            "duration": 62920,
            "durationMillis": 62920,
            "likeCount": 1641,
            "createTime": "24小时前",
            "title": "MC石头:成年人的悲哀",
            ......

于是我们的解析思路就有了:
首先通过Jsonp根据该请求url获取排行榜的json数据

String hotJsonStr = Jsoup.connect(url).ignoreContentType(true).execute().body();

根据上面的json格式,使用JsonPath对该数据进行解析,获取出所有排行榜视频的标题和链接

List<String> titles = JsonPath.read(hotJsonStr, "$.rankList.[*].title");  
List<String> urlList = JsonPath.read(hotJsonStr, "$.rankList.[*].shareUrl");

然后根据自己的喜好将标题绑定链接显示在页面制成列表就可以了