Java使用selenium爬取b站動(dòng)態(tài)的實(shí)現(xiàn)方式
目標(biāo):爬取b站用戶的動(dòng)態(tài)里面的圖片,示例動(dòng)態(tài)
如下所示,我們需要獲取這些圖片

如圖所示,嗶哩嗶哩漫畫的數(shù)據(jù)是動(dòng)態(tài)請(qǐng)求獲取的

這里我們使用selenium來(lái)爬取數(shù)據(jù)
selenium
Selenium是一個(gè)用于Web應(yīng)用程序測(cè)試的工具。Selenium測(cè)試直接運(yùn)行在瀏覽器中,就像真正的用戶在操作一樣。
這里我使用chrome瀏覽器,所以驅(qū)動(dòng)就選用chromedriver
mac安裝chromedriver
使用brew安裝
brew install chromedriver
手動(dòng)安裝
查看電腦上chrome游覽器的版本

下載對(duì)應(yīng)驅(qū)動(dòng)
選擇對(duì)應(yīng)瀏覽器版本的驅(qū)動(dòng)下載


解壓zip文件,放置到對(duì)應(yīng)文件夾
完整代碼
這里使用springboot框架
maven依賴
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>com.github.kevinsawicki</groupId>
<artifactId>http-request</artifactId>
<version>6.0</version>
</dependency>
selenium用于解析網(wǎng)頁(yè)
http-request用于下載圖片
完整代碼
package com.sun.web_crawler;
import com.github.kevinsawicki.http.HttpRequest;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class getPictures3Test {
// https://space.bilibili.com/4099287/dynamic
public static WebDriver getWebDriver(int moudle, String driverPath) {
System.setProperty("webdriver.chrome.driver", driverPath);
HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
chromePrefs.put("profile.managed_default_content_settings.images", 2);
WebDriver driver;
if (moudle == 1)
driver = new ChromeDriver(new ChromeOptions().setHeadless(true).setExperimentalOption("prefs", chromePrefs));
else
driver = new ChromeDriver();
return driver;
}
//將所有鏈接對(duì)應(yīng)的圖片下載到path中,并按照從number開始的順序編號(hào)
public static void downLoad(String path, ArrayList<String> links, int number) throws Exception {
for (String s : links) {
System.out.println("圖片:" + s);
HttpRequest hr = HttpRequest.get("https:" + s);
if (hr.ok()) {
File file = new File(path + number + s.substring(s.length() - 4));
hr.receive(file);
number++;
}
}
}
public static void main(String[] args) throws Exception {
//用戶uid
String uid = "4099287";
//圖片存儲(chǔ)位置
String dir = "/Volumes/data/data/b/tako" + File.separator;
//driver位置
String driverPath = "/Volumes/data/env/chromedriver/chromedriver";
//沒(méi)有圖片可以加載時(shí)會(huì)顯示這個(gè)
String bottomFlag = "你已經(jīng)到達(dá)了世界的盡頭";
//pt2用來(lái)匹配一個(gè)動(dòng)態(tài)里的圖片鏈接
Pattern pt2 = Pattern.compile("http://i0[^@]{50,100}(png|jpg)");
//初始化
WebDriver driver = getWebDriver(1, driverPath);
JavascriptExecutor jse = (JavascriptExecutor) driver;
ArrayList<WebElement> wes = null;
//圖片鏈接links
ArrayList<String> links = new ArrayList<String>();
driver.get("https://space.bilibili.com/" + uid + "/dynamic");
Thread.sleep(3000);
jse.executeScript("window.scrollBy(0," + 4000 + ");");
long time1 = System.currentTimeMillis();
System.out.println("開始爬取頁(yè)面圖片地址!");
int i=1;
int count=0;
while (true) {
System.out.println("向下滾動(dòng)第"+(i++)+"次!");
//向下滾動(dòng)
jse.executeScript("window.scrollBy(0," + 800 + 500 * Math.random() + ");");
//如果發(fā)現(xiàn)到底了,就退出循環(huán)
if (driver.findElement(By.className("div-load-more")).getAttribute("innerHTML").contains(bottomFlag))
break;
wes = (ArrayList<WebElement>) driver.findElements(By.className("original-card-content"));
wes.remove(wes.size() - 1);
//每20個(gè)動(dòng)態(tài)獲取一次,并刪除對(duì)應(yīng)的網(wǎng)頁(yè)元素(否則會(huì)很慢)
if (wes.size() > 20) {
for (WebElement we : wes) {
String innerHtml = we.getAttribute("innerHTML");
Matcher matcher2 = pt2.matcher(innerHtml);
while (matcher2.find()) {
String link = matcher2.group();
if (link.contains("album"))
links.add(link);
System.out.println("記錄圖片地址數(shù)量為:"+ (++count));
}
jse.executeScript("document.getElementsByClassName(\"card\")[0].remove();");
}
}
Thread.sleep(50);
}
Collections.reverse(links);
long time2 = System.currentTimeMillis();
//下載
System.out.println("開始下載圖片!");
downLoad(dir, links, 0);
long totalMilliSeconds = time2 - time1;
System.out.println();
long totalSeconds = totalMilliSeconds / 1000;
//求出現(xiàn)在的秒
long currentSecond = totalSeconds % 60;
//求出現(xiàn)在的分
long totalMinutes = totalSeconds / 60;
long currentMinute = totalMinutes % 60;
//求出現(xiàn)在的小時(shí)
long totalHour = totalMinutes / 60;
long currentHour = totalHour % 24;
//顯示時(shí)間
System.out.println("總毫秒為: " + totalMilliSeconds);
System.out.println(currentHour + ":" + currentMinute + ":" + currentSecond + " GMT");
driver.quit();
}
}
開始下載代碼時(shí)如下:

下載完成后:

完成后如下:

到此這篇關(guān)于Java使用selenium爬取b站動(dòng)態(tài)的實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)Java selenium爬取b站動(dòng)態(tài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中干掉Whitelabel Error Page返回自定義內(nèi)容的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot中干掉Whitelabel Error Page返回自定義內(nèi)容的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
MyBatis中?@Mapper?和?@MapperScan?的區(qū)別與使用解析
本文介紹了SpringBoot中MyBatis的兩個(gè)常用注解:@Mapper和@MapperScan,@Mapper用于標(biāo)記單個(gè)Mapper接口,而@MapperScan用于批量掃描指定包下的所有Mapper接口,兩者都有各自適用的場(chǎng)景,選擇合適的注解可以提高開發(fā)效率并使代碼更加簡(jiǎn)潔,感興趣的朋友一起看看吧2025-01-01
Intellij IDEA Debug調(diào)試技巧(小結(jié))
這篇文章主要介紹了Intellij IDEA Debug調(diào)試技巧(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
springcloud實(shí)現(xiàn)注冊(cè)中心Eureka
這篇文章主要介紹了springcloud實(shí)現(xiàn)注冊(cè)中心Eureka,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
Java動(dòng)態(tài)驗(yàn)證碼單線設(shè)計(jì)的兩種方法
這篇文章主要介紹了Java動(dòng)態(tài)驗(yàn)證碼單線設(shè)計(jì)的兩種方法,需要的朋友可以參考下2018-07-07
MyBatis中模糊查詢使用CONCAT('%',#{str},'%')出錯(cuò)的解
這篇文章主要介紹了MyBatis中模糊查詢使用CONCAT('%',#{str},'%')出錯(cuò)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
Java基礎(chǔ)之詳解基本數(shù)據(jù)類型的使用
今天給大家?guī)?lái)的是關(guān)于Java基礎(chǔ)的相關(guān)知識(shí),文章圍繞著基本數(shù)據(jù)類型的使用展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
SpringBoot和Vue.js實(shí)現(xiàn)的前后端分離的用戶權(quán)限管理系統(tǒng)
本文主要介紹了SpringBoot和Vue.js實(shí)現(xiàn)的前后端分離的用戶權(quán)限管理系統(tǒng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04

