使用Selenium自动给B站动态点赞教程

概要

selenium是一种简单的自动化测试的实现方式,不需要什么基础就能掌握。本人自学selenium,个人认为较为方便。这个项目用于自动给B站动态点赞。

一、获取cookies

        既然要点赞那么登录是必不可少的一步,但每次都输入账号密码又太麻烦,所以可以采用登录第一次获取cookies,之后用cookies模拟登录。selenium自带有获取cookies的方法,那么可以先创建一个“读取cookie.py”的py文件,代码如下:

from selenium import webdriver
from time import sleep
import json
def grubcookies():
    webd = webdriver.Chrome()
    webd.get('https://www.bilibili.com')
    webd.delete_all_cookies()
    sleep(50)#在这50秒内需要手动登录B站,最好扫码登录,时间不够可以自己设置
    dictcookies = webd.get_cookies()
    jsoncookies = json.dumps(dictcookies)
    with open('cookies.txt','w') as f:
        f.write(jsoncookies)

    webd.quit()
if __name__=='__main__':
    grubcookies()

运行这段代码后,在该目录下生成了一个“cookies.txt”的文件,存放着cookies,之后就不再需要获取cookies了

二、打开B站动态首页

from selenium import webdriver
webd = webdriver.Chrome()
url = 'https://t.bilibili.com/?spm_id_from=333.1007.0.0'
#url是B站动态
webd.get(url)

然而没有登录,这需要导入我们的cookies.txt文件中的cookies。

from selenium import webdriver
import json
def process():
    with open('./cookies.txt', 'r') as f:
        cookies = f.read()
    cookies = json.loads(cookies)

    for cookie in cookies:
        if 'expiry' in cookie:
            del cookie['expiry']
    #需要删除cookie中的"expiry",否则不能模拟登录动态首页只能模拟登录B站首页
    return cookies
def main():
    webd = webdriver.Chrome()
    url = 'https://t.bilibili.com/?spm_id_from=333.1007.0.0'
    webd.get(url)
    for cookie in process():
        webd.add_cookie(cookie)
    webd.refresh()#刷新登录

那么到这里就打开了B站的动态首页

三、选择用于点赞的网页元素

可以用xpath选择器或者css选择器,差不多的。

然而有一个问题:如何得知已经点赞了? 鼠标右击点赞按钮,选择检查,然后鼠标左击点赞按钮进行一次点赞操作,会发现该div节点的class属性发生变化,从div[class="bili-dyn-action like"]变为了div[class="bili-dyn-action like active"]。显而易见,可以利用这一点选择元素。

css = 'div[class="bili-dyn-item"] > div[class="bili-dyn-item__main"] > div[class="bili-dyn-item__footer"] > div[class="bili-dyn-item__action"] > div[class="bili-dyn-action like"]'
#这里采用css选择器
elements = webd.find_elements(By.CSS_SELECTOR, css)
#选择出了一列表的“点赞”元素
for i in range(len(elements)):
    #挨个对列表中的元素进行点击操作
    element = elements[i]
    #element是一个div类型元素,不能直接element.click(),要用JavaScript模拟点击
    webd.execute_script("arguments[0].click();", element)

四、循环进行网页刷新

B站动态是实时变化的,需要不断刷新获取最新动态。

这里有两个方案:

        1.当有新的动态时,会弹出一个按钮提醒你查看新动态,可以用css选择到这个元素模拟点击它。优点是不用整个网页刷新,较快。缺点是B站有时不能很及时地弹出这个按钮

        2.整页刷新,可以及时获取动态,但由于整页刷新加载慢。

那么选择哪一种呢?     答案是:都要!

可以两种结合,每次都检查是否有按钮弹出,但隔5次刷新一整页。

css_detect = 'div[class="bili-dyn-list-notification fs-small"]'
flag=0
#css选择B站自动弹出的刷新按钮
while True:
    if flag == 5:
       webd.refresh()
       flag = 0
       sleep(0.7)
    elements = webd.find_elements(By.CSS_SELECTOR, css)
    #这里的css字符串前面有
    for i in range(len(elements)):
        element = elements[i]
        webd.execute_script("arguments[0].click();", element)

    try:
        btn = webd.find_element(By.CSS_SELECTOR, css_detect)
        webd.execute_script("arguments[0].click();", btn)
        sleep(0.7)
    #注意要开头要加from selenium.common.exceptions import NoSuchElementException
    except NoSuchElementException:
        #如果不存在这个按钮元素
        pass

    sleep(1.7)
    flag += 1

五、退出程序设计

设置如何退出是很必要的一步。毕竟谁也不愿意看到每次强制关闭都报错吧。

主程序在死循环中,那么就需要使用多线程检测键盘是否按下“esc”这个键作为退出的信号

import threading
import keyboard
#keyboard模块需要自己pip install keyboard下载
def detect():
    global stop
    keyboard.wait('esc')
    stop = True
    pass
def main():
    global cnt, stop
    while True:
        if stop:
            break
    #main()大部分省略,只显示如何退出循环
    webd.quit()#退出
if __name__ == '__main__':
    stop = False
    main_thread = threading.Thread(target=main)
    detect_thread = threading.Thread(target=detect)
    #注意这里target=函数名,函数名后面不能跟括号
    detect_thread.start()
    main_thread.start()
    detect_thread.join()
    main_thread.join()

六、完善程序

可以输出点赞了谁的动态、点赞了几条动态。虽然不是很必要甚至多此一举。

def main():
    global cnt, stop
    #略
    while True:
        #略
        elements = webd.find_elements(By.CSS_SELECTOR, css)
        for i in range(len(elements)):
            element = elements[i]
            xpath = '//div[@class="bili-dyn-item__header"]/div[@class="bili-dyn-title"]/span'
            #这个xpath代表所有动态的主人的昵称,可以通过这是第几条动态进行选择
            name = element.find_elements(By.XPATH, xpath)[i].text
            print('#'+name)
            webd.execute_script("arguments[0].click();", element)
            cnt += 1
            print('已经点了' + str(cnt) + '个赞')

        #略
    webd.quit()
    pass
if __name__ == '__main__':
    cnt = 0
    #略
    print('已停止,本次一共点了{x}个赞'.format(x=cnt))

七、完整代码

1、读取cookie.py:
from selenium import webdriver
from time import sleep
import json
def grubcookies():
    webd = webdriver.Chrome()
    webd.get('https://www.bilibili.com')
    webd.delete_all_cookies()
    sleep(50)
    dictcookies = webd.get_cookies()
    jsoncookies = json.dumps(dictcookies)
    with open('cookies.txt','w') as f:
        f.write(jsoncookies)

    webd.quit()
    pass
if __name__=='__main__':
    grubcookies()
    pass
2、main.py:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from time import sleep
import json
import threading
import keyboard


def process():
    with open('./cookies.txt', 'r') as f:
        cookies = f.read()
    cookies = json.loads(cookies)

    for cookie in cookies:
        if 'expiry' in cookie:
            del cookie['expiry']

    return cookies
    pass


def main():
    global cnt, stop
    webd = webdriver.Chrome()
    url = 'https://t.bilibili.com/?spm_id_from=333.1007.0.0'
    webd.get(url)
    for cookie in process():
        webd.add_cookie(cookie)
    webd.refresh()
    css_detect = 'div[class="bili-dyn-list-notification fs-small"]'
    css = 'div[class="bili-dyn-item"] > div[class="bili-dyn-item__main"] > div[class="bili-dyn-item__footer"] > div[class="bili-dyn-item__action"] > div[class="bili-dyn-action like"]'
    sleep(5)
    flag = 0
    while True:
        if stop:
            break
        if flag == 5:
            webd.refresh()
            flag = 0
            sleep(0.7)
        elements = webd.find_elements(By.CSS_SELECTOR, css)
        for i in range(len(elements)):
            element = elements[i]
            xpath = '//../../div[@class="bili-dyn-item__header"]/div[@class="bili-dyn-title"]/span'
            name = element.find_elements(By.XPATH, xpath)[i].text
            print('#'+name)
            webd.execute_script("arguments[0].click();", element)
            cnt += 1
            print('已经点了' + str(cnt) + '个赞')

        try:
            btn = webd.find_element(By.CSS_SELECTOR, css_detect)
            webd.execute_script("arguments[0].click();", btn)
            sleep(0.7)
        except NoSuchElementException:
            pass

        sleep(1.7)
        flag += 1
    webd.quit()
    pass


def detect():
    global stop
    keyboard.wait('esc')
    stop = True
    pass


if __name__ == '__main__':
    cnt = 0
    stop = False
    main_thread = threading.Thread(target=main)
    detect_thread = threading.Thread(target=detect)
    detect_thread.start()
    main_thread.start()
    detect_thread.join()
    main_thread.join()
    print('已停止,本次一共点了{x}个赞'.format(x=cnt))

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kikzm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值