Python百度贴吧多线程自动登录签到/自动打码
本帖最后由 Hatsune_miku 于 2019-4-8 12:22 编辑自己写的百度贴吧签到脚本。基本不会漏签,签到速度约为20个贴吧每秒。
已经开源,GitHub链接:https://github.com/MikuShare/tieba_sign
来给个Star吧!!!
下面是使用教程(README)
# tieba_sign
百度贴吧多线程自动登录签到/自动打码
经测试:在三个帐号,一共207个贴吧的情况下,全部签到完成速度为12s左右。(Cookies登录情况下)
## 效果
![效果](https://raw.githubusercontent.com/MikuShare/tieba_sign/master/view.png)
## 使用教程(Centos)
1、安装Chromium
``` sh
yum install chromium
```
2、安装(https://chromedriver.storage.googleapis.com/index.html?path=73.0.3683.68/)
``` sh
wget https://chromedriver.storage.googleapis.com/73.0.3683.68/chromedriver_linux64.zip && unzip chromedriver_linux64.zip
mv chromedriver /usr/bin/ && chmod a+x /usr/bin/chromedriver
```
3、下载源码
``` sh
git clone https://github.com/MikuShare/tieba_sign/ && cd tieba_sign/
```
4、安装依赖
``` sh
pip install -r requirements.txt
```
5、修改配置文件(config.py)
``` python
users = ['用户名']
# 用户名,例如['用户1', '用户2', '用户3'] 一共3个用户
accounts = {
'用户名': {
'username': '帐号',
'password': '密码'
}
}
#用户名以及对应的帐号密码
#例如:
#accounts = {
# '用户1': {
# 'username': '用户1的帐号',
# 'password': '用户1的密码.'
# },
# '用户2': {
# 'username': '用户2的帐号',
# 'password': '用户2的密码'
# },
# '用户3': {
# 'username': '用户3的帐号',
# 'password': '用户3的密码'
# }
#}
# 一定要按照users里面的用户名顺序来填写accounts!!!
# 一定要按照users里面的用户名顺序来填写accounts!!!
# 一定要按照users里面的用户名顺序来填写accounts!!!
```
## 运行
``` sh
python tieba.py # 开始登录并签到
```
## TODO
- [ ] ~~添加打码平台~~(已完成)
- [ ] ~~添加使用Cookies签到的脚本~~(已完成)
- [ ] ~~多线程签到~~(已完成)
- [ ] ~~多账号签到~~(已完成)
## 注意事项&已知BUG
1.脚本使用Python3.7.2编写,运行的时候请使用Python3
2.Ubuntu安装Chromium的命令是:
``` sh
sudo apt-get install chromium-browser
```
3.测试在Ubuntu跟Centos都通过,Windows应该也可以,但是有些地方应该改动,后续会上传Windows的。
4.签到100个吧之后需要验证码,~~后续会解决这个问题~~(已经添加打码功能)。
5.登录时候如果验证码是中文的,也支持输入。
6.支持多账号签到。
7.使用自己训练的验证码接口。
8.有时候登录会遇到验证码+二代验证的情况,这个验证码不用打码是因为可能会出现中文验证码,我并没有训练中文模型。
9.如果遇到各种报Chrome的错,请运行:
``` sh
pkill chrome*
```
10.遇到任何问题,请提交Issues!
## ChangeLog
2019年4月7日
1.添加多线程签到,签到速度约为1秒20个贴吧。
2.去除若快打码,使用自己训练的验证码识别接口,识别速度更快,准确率可以打到99.99%。
3.增加多用户签到,自行按照config.py文件填写相应帐号密码即可。
2019年3月25日
1.修复不能正确判断验证类型的BUG(由于Centos安装的Chrome版本为71,Ubuntu为73,71版本的Chrome登录一定是验证码+二代验证,而73版本正常登录只有二代验证,所以这里判断策略出了点问题。
2019年3月20日
1.由于签到一百个贴吧之后需要验证码,所以添加了打码功能,打码平台为[若快打码](https://www.ruokuai.com/)
2.登录一次之后会自动保存cookies在本地,后续签到直接调用cookies。
## LICENSE
MIT
贴上代码
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import requests
from selenium import webdriver
from lxml import etree
from PIL import Image
import time
import re
import os
import sys
import json
import threading
import random
from io import BytesIO
from config import *
def login(user, username, passwd, url = 'https://tieba.baidu.com/index.html'):
option = webdriver.ChromeOptions()
option.add_argument('--no-sandbox')
option.add_argument('--disable-extensions')
option.add_argument('--headless')
option.add_argument('lang=zh_CN.UTF-8')
option.add_argument('--disable-gpu')
option.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(executable_path='chromedriver', options=option)
driver.get(url)
time.sleep(0.16)
print('正在登录:%s...' % user)
driver.find_element_by_xpath('//*[@id="com_userbar"]/ul/li/div/a').click() # 点击登录按钮
time.sleep(1)
driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__footerULoginBtn"]').click() # 点击用户名登录
driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__userName"]').send_keys(username) # 帐号
driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__password"]').send_keys(passwd) # 帐号
driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__submit"]').click() # 点击登录按钮
time.sleep(2.5)
try:
driver.find_element_by_xpath('//*[@id="TANGRAM__25__content_select_uname"]').click()
verification = 1 # 单二代验证
except:
print('尝试验证码 + 二代验证中...')
try:
element = driver.find_element_by_id('TANGRAM__PSP_10__verifyCodeImg')
verification = 2 # 验证码+二代验证
except:
print('可能不需要验证码验证')
if verification == 1:
time.sleep(1)
mode = input('需要二代验证,输入验证方式的序号\n1.手机验证\n2.密保邮箱验证\n请输入验证方式:')
driver.find_element_by_xpath('//*[@id="TANGRAM__25__select_email"]').click()
driver.find_element_by_xpath('//*[@id="TANGRAM__25__button_send_email"]').click()
vcode = input('请输入验证码:')
driver.find_element_by_xpath('//*[@id="TANGRAM__25__input_vcode"]').send_keys(vcode)
driver.find_element_by_xpath('//*[@id="TANGRAM__25__button_submit"]').click()
time.sleep(2.5)
cookies = driver.get_cookies()
elif verification == 2:
driver.save_screenshot("/tmp/codingpy.png")
time.sleep(3)
size = driver.find_element_by_id('TANGRAM__PSP_10__verifyCodeImg').size
left = int(element.location['x'])
top = int(element.location['y'])
right = int(element.location['x'] + element.size['width'])
bottom = int(element.location['y'] + element.size['height'])
im = Image.open('/tmp/codingpy.png')
im = im.crop((left, top, right, bottom))
im.save('code.png')
ucode = input('请打开code.png查看验证码\n验证码:')
driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__verifyCode"]').send_keys(ucode) # 输入验证码
driver.find_element_by_xpath('//*[@id="TANGRAM__PSP_10__submit"]').click() # 点击登录按钮
time.sleep(3)
driver.find_element_by_xpath('//*[@id="TANGRAM__25__content_select_uname"]').click()
time.sleep(1)
mode = input('需要二代验证,输入验证方式的序号\n1.手机验证\n2.密保邮箱验证\n请输入验证方式:')
driver.find_element_by_xpath('//*[@id="TANGRAM__25__select_email"]').click()
driver.find_element_by_xpath('//*[@id="TANGRAM__25__button_send_email"]').click()
vcode = input('请输入验证码:')
driver.find_element_by_xpath('//*[@id="TANGRAM__25__input_vcode"]').send_keys(vcode)
driver.find_element_by_xpath('//*[@id="TANGRAM__25__button_submit"]').click()
time.sleep(2.5)
cookies = driver.get_cookies()
else:
print('未知错误!')
os.system("pkill chrome*")
sys.exit(0)
print('登录成功!')
os.system("pkill chrome*")
return cookies
def gettbs(cookies, tieba):
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36'}
r = requests.get('http://tieba.baidu.com/f?kw=%s' % tieba, headers = headers, cookies = cookies)
tbslist = re.findall("'tbs':'(.+?)'", r.text)
tbstr = "".join(tbslist)
return tbstr
def getbar(cookies):
url = 'http://tieba.baidu.com/f/like/mylike?pn='
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36'}
r_bar = requests.get(url + '1', headers = headers, cookies = cookies)
webpage = etree.HTML(r_bar.text)
pages = ['1']
pns = webpage.xpath('//*[@id="j_pagebar"]/div/a') # 判断页数
for pn in pns:
if pn.text.isnumeric():
pages.append(pn.text)
tiebas = []
for pageid in pages:
r_bar_1 = requests.get(url + pageid, headers = headers, cookies = cookies)
webpage = etree.HTML(r_bar_1.text)
tag_a = webpage.xpath('//a[@title]') # 获取贴吧
for a in tag_a:
if a.text:
tiebas.append(a.text)
return tiebas
def recognize_captcha(remote_url, rec_times):
headers = {
'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36"
}
for index in range(rec_times):
# 请求
while True:
try:
response = requests.request("GET", remote_url, headers=headers, timeout=6)
if response.text:
break
else:
print("retry, response.text is empty")
except Exception as ee:
print(ee)
# 识别
url = "http://1i1.tw:10086/b"
files = {'image_file': ('captcha.jpg', BytesIO(response.content), 'application')}
r = requests.post(url=url, files=files)
# 识别结果
predict_text = json.loads(r.text)["value"]
return predict_text
def sign_vcode(tieba, tbs, captcha_input_str, captcha_vcode_str, cookies, headers):
data = {
'ie':'utf-8',
'kw':tieba,
'tbs':tbs,
'captcha_input_str':captcha_input_str,
'captcha_vcode_str':captcha_vcode_str
}
r = requests.post('http://tieba.baidu.com/sign/add', headers = headers, data = data, cookies = cookies)
try:
resp = r.json()
if resp['data']['errmsg'] == 'success':
print('贴吧:%s\t' % tieba, end = '')
print('状态:打码签到成功!')
except:
resp = r.json()
print('贴吧:%s\t' % tieba, end = '')
print('状态:%s' % resp['error'])
def sign(cookies, tieba):
tbs = gettbs(cookies, tieba)
headers = {
'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
'Origin':'http://tieba.baidu.com',
'Referer':'http://tieba.baidu.com',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36',
}
"""
data = {
'ie':'utf-8',
'tbs':tbs, # 一键签到 只能签到规定数量的贴吧
}
"""
data = {
'ie':'utf-8',
'kw':tieba,
'tbs':tbs # 分开签到
}
r = requests.post('http://tieba.baidu.com/sign/add', headers = headers, data = data, cookies = cookies)
try:
resp = r.json()
if resp['data']['errmsg'] == 'success':
print('贴吧:%s\t' % tieba, end = '')
print('状态:签到成功!')
except:
resp = r.json()
if resp['error'] == 'need vcode': # 需要验证码
captcha_vcode_str = resp['data']['captcha_vcode_str']
captcha_url = 'https://tieba.baidu.com/cgi-bin/genimg?%s' % captcha_vcode_str
captcha_input_str = recognize_captcha(captcha_url, 1)
sign_vcode(tieba,tbs,captcha_input_str,captcha_vcode_str,cookies,headers)
else:
print('贴吧:%s\t' % tieba, end = '') # 黑名单或者别的情况
print('状态:%s' % resp['error'])
def login_cookies(user, username, passwd):
cookie = login(user, username, passwd)
for item in cookie:
s.cookies.set(item['name'],item['value'])
cookies = requests.utils.dict_from_cookiejar(s.cookies)
with open('.%s' % user,'w') as fp:
json.dump(cookies,fp)
fp.close()
tiebas = getbar(cookies)
list.extend(tiebas)
threads=[]
for i in range(len(tiebas)): # 多少个贴吧就分配多少个线程
t=threading.Thread(target=sign,args=(cookies, tiebas))
threads.append(t)
for i in threads:
i.start()
for i in threads:
i.join()
s.cookies.clear()
os.system("pkill chrome*")
def main():
for x in range(len(users)):
user = users
username = accounts['username']
passwd = accounts['password']
if os.path.exists('.%s' % user):
with open('.%s' % user,'r') as fp1:
load_cookies = json.load(fp1)
cookies = requests.utils.cookiejar_from_dict(load_cookies)
print('正在使用Cookies登录:%s...' % user)
r = requests.get('http://tieba.baidu.com/sysmsg/query/userunread', cookies = cookies)
resp = r.json()
if resp['errmsg'] == '成功':
tiebas = getbar(cookies)
list.extend(tiebas)
threads=[]
for i in range(len(tiebas)):
t=threading.Thread(target=sign,args=(cookies, tiebas))
threads.append(t)
for i in threads:
i.start()
for i in threads:
i.join()
os.system("pkill chrome*")
else:
print('%sCookies失效...正在重新登录...' % user)
login_cookies(user, username, passwd)
else:
login_cookies(user, username, passwd)
if __name__ == '__main__':
list = []
s = requests.session()
start = time.time()
main()
end = time.time()
print('总共签到{}个贴吧,耗时:{}秒'.format(len(list), int(end - start))) 全球小破孩 发表于 2019-4-12 18:58
用的其他账户用的不是root账户也放到root目录下吗 还有cookies文件是config.cpython-35.pyc吗
其他账户就放在账户目录下,一般是/home/自己的用户名,cookies文件是隐藏文件格式为‘.用户名’,有个点,在Linux上可以用‘cat .‘ 连按两下tab键来查看。
https://i.loli.net/2019/04/13/5cb1784c016d8.png Hatsune_miku 发表于 2019-5-14 19:06
你帐号绑定了手机么,,建议用邮箱。
是的。按照大大的提示已成功运行。我是这样操作的:在贴吧设置关闭手机号登录,开启密保邮箱,回到程序选择2.密保邮箱验证,可以正常使用。后续将pkill改成了windows上的taskkill.exe,现在windows10中完美自动签到。感谢大大帮助! 感谢楼主分享 感谢分享,学习了 可以 谢谢楼主 很有用 哈哈 日后学习,准备自学Python 看不太懂呢……请问有更傻瓜式一点的使用方法么 比如写成exe程序的那种= = 感谢楼主分享 正在学屁眼痛3,现在工作中只用屁眼痛2,最起码10年后,屁眼痛3才会像现在的屁眼痛2一样遍地开花 现在使用助手签到,也是挺方便的 感谢分享,学习了