Python selenium贴吧水贴

Python selenium贴吧水贴

    • 前言
    • 注意!
    • 基本思路
    • 整体代码
      • 流程整理:

前言

	博主也是刚开始学习Python爬虫不久,打算通过博客来记录自己的学习历程,作为一名纯签到党,打开贴吧的时候总是觉得贴吧升级好慢,所以兴致勃勃的打算通过selenium来自动水贴。

注意!

博主在前几天发表博客后又用这个水了几天,然后现在被贴吧封禁了,故该博客仅供大家参考,如果要实现请慎重!

基本思路

	通过selenium模拟浏览器的行为进行贴吧的登陆、进入指定贴吧、打开帖子、输入水贴信息并发送。

整体代码

import json
import os
import time
import re
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

class ShuiTie():
    def __init__(self,username,userpwd,bar):
        self.wd = webdriver.Chrome()        # 打开Chrome浏览器

        # 以无头模式打开浏览器
        '''
        opt = Options()
        opt.add_argument('--headless')
        opt.add_argument('--disable-gpu')
        self.wd = webdriver.Chrome(options=opt)
        '''
        self.wd.set_window_size(1280, 800)  # 设置宽度和高度
        self.wd.implicitly_wait(5)          # 设置隐式等待为5秒
        self.url = 'https://tieba.baidu.com'
        self.wd.get(self.url)
        self.username = username
        self.userpwd = userpwd
        self.bar = bar
        self.Login()            # 登陆百度贴吧
        self.pos_url = []       # 存储获取到的帖子的链接
        self.Select_Bar()       # 选择进入的贴吧
        self.Get_Url()          # 获取当前首页所有帖子的链接
        self.Send_Msg()         # 在每个帖子中回复消息

    def Login(self):
        if(os.path.exists('Cookies_tieba.json')==True): # 若存储Cookie的文件是否存在
            self.Add_cookies()
            self.wd.refresh()
            # 获取当前的网页内容,通过find方法查找用户名,判断用户是否登录成功
            content = self.wd.page_source
            if (content.find(self.username) == -1):     # 用户登录失败,判断Cookie过期,删除文件
                os.remove('Cookies_tieba.json')
                print('Cookie已过期,请手动登录一次获取Cookie')
                return False
            else:
                print('登录成功!')

        else:                                           # 若存储Cookie的文件不存在
            # 点击登录按钮
            self.wd.find_elements_by_xpath('//*[@id="com_userbar"]/ul/li[4]/div/a')[0].click()
            # 点击通过用户名密码登陆
            self.wd.find_element_by_id('TANGRAM__PSP_10__footerULoginBtn').click()
            # 输入用户名及密码
            self.wd.find_element_by_id('TANGRAM__PSP_10__userName').send_keys(self.username)
            self.wd.find_element_by_id('TANGRAM__PSP_10__password').send_keys(self.userpwd)
            time.sleep(1)
            # 点击登录按钮
            self.wd.find_element_by_id('TANGRAM__PSP_10__submit').click()
            # 贴吧登陆大概率需要验证,此处留下60秒验证登陆
            time.sleep(60)
            self.Save_cookies()
        return True

    def Save_cookies(self):         # 通过json格式保存Cookie
        with open('Cookies_tieba.json', 'w') as f:
            json.dump(self.wd.get_cookies(), f)

    def Add_cookies(self):      # 读取Cookie并添加到浏览器中
        with open('Cookies_tieba.json','r') as f:
            Cookies = json.load(f)
        for cookie in Cookies:
            cookie_dict = {
                "domain": ".tieba.baidu.com",
                'name': cookie.get('name'),
                'value': cookie.get('value'),
                "expires": "",
                'path': '/',
                'httpOnly': False,
                'HostOnly': False,
                'Secure': False }
            self.wd.add_cookie(cookie_dict)

    def Select_Bar(self):       # 在搜索框输入要进入的贴吧并点击进入
        self.wd.find_element_by_id('wd1').send_keys(self.bar)
        time.sleep(1)
        self.wd.find_element_by_xpath('//*[@id="tb_header_search_form"]/span[1]/a').click()

    def Get_Url(self):          # 获取当前首页的帖子的链接
        html = self.wd.page_source
        # 此处本来是想用xpath来获取链接的,但是要获取的路径class标签中有空格,试了一下通过xpath没有获取到,
        # 后改用re来匹配,用re匹配有一个缺点,会匹配到置顶帖,包括吧规贴...所以在后续发送信息时会跳过这些帖子
        res = ''
        self.pos_url = re.findall(res,html)         # 存储首页所有帖子的链接

    def Send_Msg(self):
        with open('Msg.txt','r',encoding='utf-8') as f: # 读取水贴的信息
            Msg = f.readlines()
        for i in range(2,len(self.pos_url)):        # 这里我是进入的滑稽吧,有两条置顶帖,在这里跳过
            msg = Msg[i%len(Msg)]                   # 循环选取要发送的信息
            url = self.url+self.pos_url[i]          # 获取帖子的链接
            self.wd.get(url)
            title = self.wd.find_element_by_xpath('//h3').text      # 获取帖子的主题
            js = "window.scrollTo(0, document.body.scrollHeight)"
            self.wd.execute_script(js)                              # 滑动滚动条到底部
            time.sleep(3)
            self.wd.find_element_by_id('ueditor_replace').send_keys(msg)    # 向输入框中添加信息
            self.wd.find_element_by_xpath('//div[@class="j_floating"]//a[@title="Ctrl+Enter快捷发表"]').click()
            print(f"水贴成功:{url},主题为:{title} 发送消息为:{msg}")
            time.sleep(30)      # 水贴间隔

if __name__ == '__main__':
    Exp = ShuiTie('你的贴吧用户名,'你的贴吧密码','贴吧名')

流程整理:

  1. 打开浏览器并进入贴吧主页
    通过webdriver打开谷歌浏览器,可以选择用无头模式打开。在这里设置了浏览器的宽度和高度以及隐式等待等,通过get方法进入贴吧的主页
        self.wd = webdriver.Chrome()        # 打开Chrome浏览器
        
        # 以无头模式打开浏览器
        '''
        opt = Options()
        opt.add_argument('--headless')
        opt.add_argument('--disable-gpu')
        self.wd = webdriver.Chrome(options=opt)
        '''
        self.wd.set_window_size(1280, 800)  # 设置宽度和高度
        self.wd.implicitly_wait(5)          # 设置隐式等待为5秒
        self.url = 'https://tieba.baidu.com'
        self.wd.get(self.url)

打开贴吧主页:
Python selenium贴吧水贴_第1张图片
2. 登陆贴吧
登陆的cookie存储在本地Cookies_tieba.json文件中,首先判断该文件是否存在,若存在则尝试添加cookie判断能否直接登陆成功,如果cookie过期或者没有该json文件则会打开贴吧的登陆界面输入用户名和密码并点击登录,需要注意的是不用cookie登陆的话基本上都会需要验证,所以我设置了延时来手动登陆贴吧。

    def Login(self):
        if(os.path.exists('Cookies_tieba.json')==True): # 若存储Cookie的文件是否存在
            self.Add_cookies()
            self.wd.refresh()
            # 获取当前的网页内容,通过find方法查找用户名,判断用户是否登录成功
            content = self.wd.page_source
            if (content.find(self.username) == -1):     # 用户登录失败,判断Cookie过期,删除文件
                os.remove('Cookies_tieba.json')
                print('Cookie已过期,请手动登录一次获取Cookie')
                return False
            else:
                print('登录成功!')

        else:                                           # 若存储Cookie的文件不存在
            # 点击登录按钮
            self.wd.find_elements_by_xpath('//*[@id="com_userbar"]/ul/li[4]/div/a')[0].click()
            # 点击通过用户名密码登陆
            self.wd.find_element_by_id('TANGRAM__PSP_10__footerULoginBtn').click()
            # 输入用户名及密码
            self.wd.find_element_by_id('TANGRAM__PSP_10__userName').send_keys(self.username)
            self.wd.find_element_by_id('TANGRAM__PSP_10__password').send_keys(self.userpwd)
            time.sleep(1)
            # 点击登录按钮
            self.wd.find_element_by_id('TANGRAM__PSP_10__submit').click()
            # 贴吧登陆大概率需要验证,此处留下60秒验证登陆
            time.sleep(60)
            self.Save_cookies()
        return True

登录后效果:
Python selenium贴吧水贴_第2张图片

  1. 进入指定贴吧
    在贴吧搜索框中输入要进入的贴吧的名称,并点击进入贴吧按钮
    def Select_Bar(self):       # 在搜索框输入要进入的贴吧并点击进入
        self.wd.find_element_by_id('wd1').send_keys(self.bar)
        time.sleep(1)
        self.wd.find_element_by_xpath('//*[@id="tb_header_search_form"]/span[1]/a').click()

在贴吧搜索框中自动输入贴吧名并点击进入贴吧:
Python selenium贴吧水贴_第3张图片

  1. 获取首页帖子的链接
    通过page_source获取到网页内容,通过正则表达式来匹配网页中的帖子的链接
    def Get_Url(self):
    	# 获取网页的内容
        html = self.wd.page_source
        # 此处本来是想用xpath来获取链接的,但是要获取的路径class标签中有空格,试了一下通过xpath没有获取到,
        # 后改用re来匹配,用re匹配有一个缺点,会匹配到置顶帖,包括吧规贴...所以在后续发送信息时会跳过这些帖子
        res = ''
        self.pos_url = re.findall(res,html)         # 存储首页所有帖子的链接

这里我将获取到的链接放在文件中展示:
Python selenium贴吧水贴_第4张图片
5. 水贴
博主是将水贴信息存储在Msg文件中的,因为有中文,所以需要编码成utf-8,通过for循环遍历之前获得的帖子的链接,注意在这里需要跳过置顶帖,毕竟有些置顶帖例如吧规贴是不予许随便水的。此处博主还遇到一个问题就是消息的输入框是在网页的底端,直接定位输入框是不行的,需要将网页下滑至底端然后再定位。

    def Send_Msg(self):
        with open('Msg.txt','r',encoding='utf-8') as f: # 读取水贴的信息
            Msg = f.readlines()
        for i in range(2,len(self.pos_url)):        # 这里我是进入的滑稽吧,有两条置顶帖,在这里跳过
            msg = Msg[i%len(Msg)]                   # 循环选取要发送的信息
            url = self.url+self.pos_url[i]          # 获取帖子的链接
            self.wd.get(url)
            title = self.wd.find_element_by_xpath('//h3').text      # 获取帖子的主题
            js = "window.scrollTo(0, document.body.scrollHeight)"
            self.wd.execute_script(js)                              # 滑动滚动条到底部
            time.sleep(3)
            self.wd.find_element_by_id('ueditor_replace').send_keys(msg)    # 向输入框中添加信息
            self.wd.find_element_by_xpath('//div[@class="j_floating"]//a[@title="Ctrl+Enter快捷发表"]').click()
            print(f"水贴成功:{url},主题为:{title} 发送消息为:{msg}")
            time.sleep(30)      # 水贴间隔

建议水贴间隔不要调的太低,毕竟不知道会不会被封号…
Python selenium贴吧水贴_第5张图片

你可能感兴趣的:(Python爬虫)