Java使用selenium爬取b站動態(tài)的實現(xiàn)方式
目標(biāo):爬取b站用戶的動態(tài)里面的圖片,示例動態(tài)
如下所示,我們需要獲取這些圖片
如圖所示,嗶哩嗶哩漫畫的數(shù)據(jù)是動態(tài)請求獲取的
這里我們使用selenium來爬取數(shù)據(jù)
selenium
Selenium是一個用于Web應(yīng)用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。
這里我使用chrome瀏覽器,所以驅(qū)動就選用chromedriver
mac安裝chromedriver
使用brew安裝
brew install chromedriver
手動安裝
查看電腦上chrome游覽器的版本
下載對應(yīng)驅(qū)動
選擇對應(yīng)瀏覽器版本的驅(qū)動下載
解壓zip文件,放置到對應(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)頁
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; } //將所有鏈接對應(yīng)的圖片下載到path中,并按照從number開始的順序編號 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"; //圖片存儲位置 String dir = "/Volumes/data/data/b/tako" + File.separator; //driver位置 String driverPath = "/Volumes/data/env/chromedriver/chromedriver"; //沒有圖片可以加載時會顯示這個 String bottomFlag = "你已經(jīng)到達(dá)了世界的盡頭"; //pt2用來匹配一個動態(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("開始爬取頁面圖片地址!"); int i=1; int count=0; while (true) { System.out.println("向下滾動第"+(i++)+"次!"); //向下滾動 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個動態(tài)獲取一次,并刪除對應(yīng)的網(wǎng)頁元素(否則會很慢) 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)在的小時 long totalHour = totalMinutes / 60; long currentHour = totalHour % 24; //顯示時間 System.out.println("總毫秒為: " + totalMilliSeconds); System.out.println(currentHour + ":" + currentMinute + ":" + currentSecond + " GMT"); driver.quit(); } }
開始下載代碼時如下:
下載完成后:
完成后如下:
到此這篇關(guān)于Java使用selenium爬取b站動態(tài)的實現(xiàn)方式的文章就介紹到這了,更多相關(guān)Java selenium爬取b站動態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot四大神器之Actuator的使用小結(jié)
這篇文章主要介紹了SpringBoot四大神器之Actuator的使用小結(jié),詳細(xì)的介紹了Actuator的使用和端點的使用,有興趣的可以了解一下2017-11-11Java方法遞歸的形式和常見遞歸算法(方法遞歸結(jié)合File類查找文件)
方法遞歸方法直接調(diào)用自己或者間接調(diào)用自己的形式稱為方法遞歸( recursion),遞歸做為一種算法在程序設(shè)計語言中廣泛應(yīng)用,這篇文章主要介紹了Java方法遞歸的形式和常見遞歸算法-方法遞歸結(jié)合File類查找文件,需要的朋友可以參考下2023-02-02springboot FeignClient注解及參數(shù)
這篇文章主要介紹了springboot FeignClient注解及參數(shù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12springboot?pom文件加入監(jiān)控依賴后沒有起作用的解決
這篇文章主要介紹了springboot?pom文件加入監(jiān)控依賴后沒有起作用的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02