Java使用selenium爬取b站动态的实现方式
作者:孙霸天
本文主要介绍了Java使用selenium爬取b站动态的实现方式,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
目标:爬取b站用户的动态里面的图片,示例动态
如下所示,我们需要获取这些图片
如图所示,哔哩哔哩漫画的数据是动态请求获取的
这里我们使用selenium来爬取数据
selenium
Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
这里我使用chrome浏览器,所以驱动就选用chromedriver
mac安装chromedriver
使用brew安装
brew install chromedriver
手动安装
查看电脑上chrome游览器的版本
下载对应驱动
选择对应浏览器版本的驱动下载
解压zip文件,放置到对应文件夹
完整代码
这里使用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用于解析网页
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; } //将所有链接对应的图片下载到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 = "你已经到达了世界的尽头"; //pt2用来匹配一个动态里的图片链接 Pattern pt2 = Pattern.compile("//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() + ");"); //如果发现到底了,就退出循环 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个动态获取一次,并删除对应的网页元素(否则会很慢) 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("记录图片地址数量为:"+ (++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; //求出现在的秒 long currentSecond = totalSeconds % 60; //求出现在的分 long totalMinutes = totalSeconds / 60; long currentMinute = totalMinutes % 60; //求出现在的小时 long totalHour = totalMinutes / 60; long currentHour = totalHour % 24; //显示时间 System.out.println("总毫秒为: " + totalMilliSeconds); System.out.println(currentHour + ":" + currentMinute + ":" + currentSecond + " GMT"); driver.quit(); } }
开始下载代码时如下:
下载完成后:
完成后如下:
到此这篇关于Java使用selenium爬取b站动态的实现方式的文章就介绍到这了,更多相关Java selenium爬取b站动态内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!