java獲取B站彈幕文件的兩種方案

(一)實現思路

1,定位彈幕文件

通常用json或xml格式來保存彈幕,因此咱們只要找到視頻網頁裏面的xml文件或json文件,就能定位到彈幕文件。html

2,解析彈幕文件

而後經過jsoup解析文件,提取咱們彈幕的文本內容。java

(二)第一個實現方案,解析本地文件

1,定位彈幕文件

好比咱們但願爬取下方視頻的彈幕文件。 node

image.png

打開Chrome的Network後刷新網頁,再輸入框中輸入xml篩選出xml文件資源: git

image.png

光標移動到該文件上,能夠看到該文件具體地址以下: apache

image.png

在該文件上右鍵Open in new tab就能夠在新的瀏覽器頁面查看該彈幕文件內容: json

image.png

2,解析彈幕文件

2.1 建立基本的maven項目

image.png

輸入GroupId和ArtifactId 瀏覽器

image.png

本項目中會使用到jsoup這個jar包,因而在項目根目錄下建立lib目標,把jar拷貝進去,而後按下面操做將jar包構建到項目中: bash

image.png

選中該jar並點擊OK。 服務器

image.png

2.2 在項目根目錄下建立彈幕文件

在根目錄下建立3232417.xml文件,複製https://comment.bilibili.com/3232417.xml彈幕頁面的內容,保存到該文件中。直接全選複製過去便可,咱們後面解析文件的時候只會提取有用的文本,因此第一行內容不用去除,以下: maven

image.png

2.3 代碼實現

解析本地彈幕xml文件的代碼以下:

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

import java.io.File;
import java.util.ArrayList;

/**
 * Created by shuhu on 2018/1/20.
 */
public class LocalFile {

    public static ArrayList<String> getData(String fileName){
        ArrayList<String> list = new ArrayList<String>();
        try{
            File input = new File(fileName);
            Document doc = Jsoup.parse(input, "UTF-8");
            //每條彈幕的內容都處於<d></d>標籤中,因而根據該標籤找到全部彈幕
            Elements contents = doc.getElementsByTag("d");

            for (Element content : contents) {
                list.add(content.text()); //將<d></d>標籤中的文本內容,也就是彈幕內容,添加到list中
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
}
複製代碼

在入口類Main.java中調用LocalFile類的getData方法,傳入參數爲xml文件名,解析每條彈幕並輸出:

import java.util.ArrayList;

/**

 * Created by shuhu on 2018/1/20.

 */
public class Main {
    public static void main(String[] args){
        ArrayList<String> items = new ArrayList<String>();
        //1,經過解析本地文件的方式獲得全部彈幕

        items = LocalFile.getData("3232417.xml");

        //遍歷輸出每條彈幕

        for (String item : items) {
            System.out.println(item);
        }
    }
}
複製代碼

輸出結果以下:

image.png

(三)第二個實現方案,解析遠程服務器文件

1,添加httpclient依賴

因爲須要訪問遠程服務器,因此用到了相關的依賴,該依賴提供了對http服務器的訪問功能。在pom.xml文件中添加:

<dependencies>
        <!--提供了對http服務器的訪問功能-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.3</version>
        </dependency>
    </dependencies>
複製代碼

2,實現代碼

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.ArrayList;

/**
 * Created by shuhu on 2018/1/20.
 */
public class RemoteFile {

    public static ArrayList<String> getData(String fileName)  throws IOException {
        ArrayList<String> list = new ArrayList<String>();
        //1,建立HttpClient對象,咱們使用到Apache中的HttpClient的實例CloseableHttpClient
        CloseableHttpClient httpclient = HttpClients.createDefault();
        //2,建立HttpGet請求實例,該實例指示向目標URL發起GET請求
        HttpGet httpGet = new HttpGet(fileName);
        //3,執行HttpGet請求實例,也就是發起GET請求,響應結果保存到httpResponse變量中
        CloseableHttpResponse httpResponse = httpclient.execute(httpGet);
        try {
            //4,獲得彈幕文件的文件內容
            HttpEntity httpEntity = httpResponse.getEntity();
            String httpHtml = EntityUtils.toString(httpEntity);

            //5,解析彈幕文件,把每條彈幕放入list中
            Document doc = Jsoup.parse(httpHtml, "UTF-8");
            Elements contents = doc.getElementsByTag("d");
            for (Element content : contents) {
                list.add(content.text()); //將<d></d>標籤中的文本內容,也就是彈幕內容,添加到list中
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            httpResponse.close();
        }
        return list;
    }
}
複製代碼

CloseableHttpResponse httpResponse = httpclient.execute(httpGet);執行完GET請求後,響應結果存放在httpResponse中。response.getEntity()是響應結果中的消息實體,由於響應結果中還包含其餘內容好比Headers等以下圖,這裏咱們只須要關注getEntity()消息實體便可。

image.png
EntityUtils.toString(response.getEntity());返回的是服務端以流的形式寫出的響應內容,好比在服務端調用的方法最後爲: responseWriter.write("just do it");那麼 EntityUtils.toString(response.getEntity());獲取的就是 just do it 這句話。 這裏能夠簡單理解爲網頁的html代碼,即右鍵查看網頁源代碼看到的所有html代碼。咱們須要解析的就是這樣的html代碼。

在入口類Main.java中調用RemoteFile類的getData方法,傳入參數爲xml文件名,解析每條彈幕並輸出:

import java.util.ArrayList;

/**

 * Created by shuhu on 2018/1/20.

 */
public class Main {
    public static void main(String[] args){
        ArrayList<String> items = new ArrayList<String>();
        //1,經過解析本地文件的方式獲得全部彈幕

//        items = LocalFile.getData("3232417.xml");


        //2,經過解析遠程服務器文件的方式獲得全部彈幕

        items = RemoteFile.getData("https://comment.bilibili.com/3232417.xml");

        //遍歷輸出每條彈幕

        for (String item : items) {
            System.out.println(item);
        }
    }
}
複製代碼

輸出結果以下:

image.png

項目代碼

代碼倉庫: 完整項目代碼

相關文章
相關標籤/搜索