博主也是刚开始学习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('你的贴吧用户名,'你的贴吧密码','贴吧名')
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)
打开贴吧主页:
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
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) # 存储首页所有帖子的链接
这里我将获取到的链接放在文件中展示:
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) # 水贴间隔