(一)實現思路
1,定位彈幕檔案
一般用json或xml格式來儲存彈幕,所以我們只要找到視訊網頁裡面的xml檔案或json檔案,就能定位到彈幕檔案。
2,解析彈幕檔案
然後通過jsoup解析檔案,提取我們彈幕的文字內容。
(二)第一個實現方案,解析本地檔案
1,定位彈幕檔案
比如我們希望爬取下方視訊的彈幕檔案。
開啟Chrome的Network後重新整理網頁,再輸入框中輸入xml篩選出xml檔案資源:
游標移動到該檔案上,可以看到該檔案具體地址如下:
在該檔案上右鍵Open in new tab就可以在新的瀏覽器頁面檢視該彈幕檔案內容:
2,解析彈幕檔案
2.1 建立基本的maven專案
輸入GroupId和ArtifactId
本專案中會使用到jsoup這個jar包,於是在專案根目錄下建立lib目標,把jar拷貝進去,然後按下面操作將jar包構建到專案中:
選中該jar並點選OK。
2.2 在專案根目錄下建立彈幕檔案
在根目錄下建立3232417.xml檔案,複製https://comment.bilibili.com/3232417.xml
彈幕頁面的內容,儲存到該檔案中。直接全選複製過去即可,我們後面解析檔案的時候只會提取有用的文字,所以第一行內容不用去除,如下:
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);
}
}
}
複製程式碼
輸出結果如下:
(三)第二個實現方案,解析遠端伺服器檔案
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()訊息實體即可。
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);
}
}
}
複製程式碼
輸出結果如下:
專案程式碼
程式碼倉庫: 完整專案程式碼