Java使用selenium爬取b站动态的实现方式

 更新时间:2022年01月17日 08:34:49   作者:孙霸天  
本文主要介绍了Java使用selenium爬取b站动态的实现方式,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

目标:爬取b站用户的动态里面的图片,示例动态

如下所示,我们需要获取这些图片

image-20220116221456470

如图所示,哔哩哔哩漫画的数据是动态请求获取的

image-20220116221751682

这里我们使用selenium来爬取数据

selenium

Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。

官网地址

这里我使用chrome浏览器,所以驱动就选用chromedriver

mac安装chromedriver

使用brew安装

brew install chromedriver

手动安装

查看电脑上chrome游览器的版本

image-20220116222550463

下载对应驱动

chromedriver下载官网

选择对应浏览器版本的驱动下载

image-20220116222829089

image-20220116222845433

解压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();
    }
}

开始下载代码时如下:

image-20220116224709802

下载完成后:

image-20220116225211086

完成后如下:

image-20220116225303392

 到此这篇关于Java使用selenium爬取b站动态的实现方式的文章就介绍到这了,更多相关Java selenium爬取b站动态内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • java实现字符串转String数组的方法示例

    java实现字符串转String数组的方法示例

    这篇文章主要介绍了java实现字符串转String数组的方法,涉及java字符串的遍历、分割、转换等相关操作技巧,需要的朋友可以参考下
    2017-10-10
  • 详解Mybatis逆向工程中使用Mysql8.0版本驱动遇到的问题

    详解Mybatis逆向工程中使用Mysql8.0版本驱动遇到的问题

    今天在使用 8.0.12 版的 mysql 驱动时遇到了各种各样的坑。这篇文章主要介绍了详解Mybatis逆向工程中使用Mysql8.0版本驱动遇到的问题,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • Spring Initializr只能创建为Java 17版本以上的问题解决

    Spring Initializr只能创建为Java 17版本以上的问题解决

    这篇文章主要给大家介绍了关于Spring Initializr只能创建为Java 17版本以上问题的解决办法,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-01-01
  • Java中的继承详情

    Java中的继承详情

    这篇文章主要介绍了Java中的继承详情,继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法,下文介绍需要的朋友可以参考下
    2022-04-04
  • Java写出生肖年判断

    Java写出生肖年判断

    本篇文章主要给大家分享一篇关于用JAVA写出生肖判断的小功能,有兴趣的跟着学习下。
    2018-02-02
  • Java switch关键字原理及用法详解

    Java switch关键字原理及用法详解

    这篇文章主要介绍了Java中 switch关键原理及用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • java并发高的情况下用ThreadLocalRandom来生成随机数

    java并发高的情况下用ThreadLocalRandom来生成随机数

    如果我们想要生成一个随机数,通常会使用Random类。但是在并发情况下Random生成随机数的性能并不是很理想,本文主要介绍了java并发高的情况下用ThreadLocalRandom来生成随机数,感兴趣的可以了解一下
    2022-05-05
  • 浅谈java object对象在heap中的结构

    浅谈java object对象在heap中的结构

    本文主要介绍了浅谈java object对象在heap中的结构,感兴趣的同学,可以参考下。
    2021-06-06
  • Visual Studio Code配置Tomcat运行Java Web项目详细步骤

    Visual Studio Code配置Tomcat运行Java Web项目详细步骤

    VS Code是一款非常棒的文本编辑器,具有配置简单、功能丰富、轻量简洁的特点,并且极其适合处理中小规模的代码,这篇文章主要给大家介绍了关于Visual Studio Code配置Tomcat运行Java Web项目的详细步骤,需要的朋友可以参考下
    2023-11-11
  • 完美解决docx4j变量替换的问题

    完美解决docx4j变量替换的问题

    这篇文章主要介绍了完美解决docx4j变量替换的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07

最新评论