使用Python+Selenium实现B站自动评论、点赞、发弹幕(一)

1,442 阅读3分钟

前提

之前看到有些视频下出现大量重复评论和重复弹幕,就想这个刷评论的操作应该不难用实现,于是就尝试了一下。目前基础可以实现,后续更新也是随缘,就当是一次小小的练习了。

声明

  1. 此功能是根据查找用户的UID,来对UP主的视频进行操作
  2. 目前只可以给UP主首页的视频进行操作
  3. 第一次登录需要手动获取Cookie
  4. 点赞功能未优化需要,若存在已经点过赞的视频会报错

准备工作

  1. 编译环境:Python3.10
  1. 使用技术:selenium
  • selenium在使用中避不开浏览器的版本和对应的webdriver的下载,根据浏览器版本下载对应的驱动。谷歌webdriver下载地址

image.png

  • 下载后保存在浏览器的文件目录即可,方便后续省略配置路径

通用的类

这个模块我分了两部分,这一部分是后续中常用的操作给提炼了出来,提高代码复用。

  1. 初始化对象
  • 创建浏览器驱动,把浏览器通过后续获取的元素进行对页面的操作
  1. cookie获取
  • 此行为设计登录操作,以第一次手动登录来获取cookie写入到文件中,后续登录只需对文件的读取。
  1. 更新当前页面
  • webdriver的窗口识别需要手动更新,此行为在涉及到页面过多的行为时可封装次操作,打开多个窗口后,获取到最新打开的页面。

      # @Time : 2023/3/27 20:33
      # @auth : 都是好事
      # @Email : 
      # @Content : My_webApi.py
      from selenium import webdriver
      from selenium.webdriver.chrome.options import Options
      import chardet
    
    
      class Any_Api:
    
          # 去掉自动化标识,创建webdriver对象
          def getWeb(self, htp):
              option = Options()
              option.add_experimental_option('excludeSwitches', ['enable-automation'])
              option.add_argument('--disable-blink-features=AutomationControlled')
    
              wb = webdriver.Chrome(options=option)
              wb.implicitly_wait(3)
              wb.get(htp)
              wb.maximize_window()
              return wb
    
          # 写入文件
          def check_charset(self, file_path):
              with open(file_path, "rb") as f:
                  data = f.read(4)
                  charset = chardet.detect(data)['encoding']
              return charset
    
          # 手动登录获取cookie
          def get_cookies(self, wb, filepath):
              cok = wb.get_cookies()
              with open(filepath, 'w', encoding=self.check_charset(filepath)) as f:
                  for i in cok:
                      f.write(str(i))
                      f.write('\n')
    
          # 使用之前获取的cookie登录
          def set_cookies(self, wb, filepath):
              cookies = []
              with open(filepath, 'r', encoding=self.check_charset(filepath)) as f:
                  for i in f:
                      cookies.append(eval(i.strip()))
    
              for i in cookies:
                  wb.add_cookie(i)
    
          def now_win(self, wb):
              # 获取打开的多个窗口句柄
              windows = wb.window_handles
              # 切换到当前最新打开的窗口
              wb.switch_to.window(windows[-1])
             
    

具体实现

在具体实现这一环境,设计的操作分为

  1. 模块导入:time,WebDriverWait
  • 网络的环境因人而异,视频过大也可能导致页面元素加载问题,强制等待和显示等待可根据情况使用
  1. 根据初始化内容获取页面元素执行操作

    # @Time : 2023/3/27 20:28
    # @auth : 都是好事
    # @Email : 
    # @Content : bilibili.py
    import time
    from selenium.webdriver.common.by import By
    # 显式等待模块
    from selenium.webdriver.support.ui import WebDriverWait
    # 显式等待条件
    from selenium.webdriver.support import expected_conditions as EC
    # 导入上文中的代码
    from anyUser import My_webApi

    # 调用封装的通用类
    anp = My_webApi.Any_Api()
    wb = anp.getWeb(htp="https://www.bilibili.com/")

    # input()
    cookiePath = '这里填存放cookie文件的路径'
    # 手动登录获取cookie
    # anp.get_cookies(wb, cookiePath)

    # 使用获取的cookie登录
    anp.set_cookies(wb, cookiePath)

    # 等待登录主页刷新
    time.sleep(3)
    wb.refresh()

    # 输入UID进入个人主页
    sea_inp = wb.find_element(By.XPATH, '//input[@class="nav-search-input"]')
    sea_inp.click()
    sea_inp.send_keys('UIDxxxxxxxx')

    sea_but = wb.find_element(By.XPATH, '//div[@class="nav-search-btn"]')
    sea_but.click()

    anp.now_win(wb)

    time.sleep(3)
    user = wb.find_elements(By.XPATH, '//img[@data-src="https://i1.hdslb.com/bfs/face/96d230df1219334fcbc4531b524a674d8151b2f8.jpg@240w_240h_1c_1s.webp"]')
    user[0].click()

    anp.now_win(wb)
    window = wb.current_window_handle
    # 遍历视频,发送评论
    # 设置显式等待
    wdw = WebDriverWait(wb, 10, 0.5)
    viods = wb.find_elements(By.XPATH, '//a[@class="title"]')
    for i in viods:
        i.click()
        anp.now_win(wb)
        # 评论
        txta = wdw.until(
            EC.presence_of_element_located((By.XPATH, '//textarea[@class="reply-box-textarea"]')))
        txta.send_keys('up主你做的真好')

        fb_but = wb.find_element(By.XPATH, '//div[@class="send-text"]')
        fb_but.click()
        # 弹幕
        danmu = wdw.until(
            EC.presence_of_element_located((By.XPATH, '//input[@placeholder="发个友善的弹幕见证当下"]')))
        danmu.send_keys('每日一遍')

        next_btn = wb.find_element(By.XPATH, '//div[@class="bui-area bui-button-blue"]')
        wb.execute_script("arguments[0].click();", next_btn)

        # 点赞
        like = wb.find_element(By.XPATH, '//span[@class="like"]')
        like.click()
        wb.switch_to.window(window)

    input()

后续思路

  1. 优化点赞功能:准备用显示等待获取点赞图标,对已点赞的视频进行处理
  2. 多个账号刷评:提前准备好大量账号的Cookie,刷评操作完成后切换用户
  3. 其余内容:投币功能实现,关注功能实现,转发功能实现,收藏功能实现