python贴吧自动签到,解放你的双手

本文原地址

目录

注意事项
配置文件
贴吧登陆过程分析
贴吧签到
完整代码

注意事项

贴吧签到是在登陆百度账号的基础上进行的,所以首先需要知道如何获取百度账号的授权cookie,具体可参考:python模拟登陆百度

配置文件config

该文件配置了请求头等信息

# -*- coding: utf-8 -*-
headers = {
    'passport_headers':{
        'Host': 'passport.baidu.com',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
        'Refer': 'https://www.baidu.com/?tn=62095104_7_oem_dg'

    },
    'tieba_headers':{
        'Host': 'tieba.baidu.com',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
        'Refer': 'https://www.baidu.com/?tn=62095104_7_oem_dg',
        'Origin': 'https://tieba.baidu.com'
    }
}

贴吧登陆过程分析

我们知道,登陆百度以后,是不需要再次验证就可以访问贴吧的,所以贴吧的授权cookie是否和百度账号的授权cookie是一致的呢?,为了验证,我们利用百度账号的授权cookie来访问贴吧首页,看是否能得到我们需要的信息。关于如何获取百度账号的授权cookie可参考:python模拟登陆百度。假设百度账号的授权信息已经以json的方式存入到auth_cookies.txt文件中,则访问贴吧首页的代码如下:

import config
 with open('auth_cookies.txt', 'r') as f:
 	cookiesstr = f.read()
 	auth_cookies = json.loads(cookiesstr)

tieba_url = 'https://tieba.baidu.com/index.html'
tieba_r = requests.get(tieba_url, cookies=passport_authcookies, headers=config.headers['tieba_headers'])
print(tieba_r.text)

运行上面的程序可以发现程序报错,错误原因如下

这个错误的意思是该请求重定向次数过多,这与我们预期的竟然不一样,利用百度账号的授权cookie不能直接访问百度贴吧。但是我们在网页上明明登陆了百度账号后是直接可以访问贴吧相关内容的。为了探究这个问题,我们在网页上登陆百度账号后,先删除贴吧相关cookie,再次访问贴吧,利用浏览器的开发者模式进行请求追踪。
** 删除贴吧cookie: ** 如下图,删除域名tieba.baidu.com下的所有cookie,若没有,则不进行任何操作。
python贴吧自动签到,解放你的双手_第1张图片
打开浏览器开发者模式,访问贴吧首页 https://tieba.baidu.com/index.html,追踪到的访问信息如下:


可以看到,该请求经过了三次重定向才到达了真正的贴吧首页,可以预测的是,重定向的过程肯定设置或更新了新的授权cookie。依次对这三个请求进行分析:


第一个请求的具体信息如下:
python贴吧自动签到,解放你的双手_第2张图片

可以看出,该请求利用了之前获得到的百度账号授权cookie中的BAIDUID,BUDSS两个参数,并设置了TIEBA_USERTYPE这个cookie`


第二个请求的具体信息如下:
python贴吧自动签到,解放你的双手_第3张图片
python贴吧自动签到,解放你的双手_第4张图片
可以看到,该请求并未设置任何cookie,但是,该请求的地址https://passport.baidu.com/v3/login/api/auth/,这正是为了验证百度账号授权信息的有效性。


第三个请求的具体信息如下:
python贴吧自动签到,解放你的双手_第5张图片
从图中表红的地方可以看出,该请求利用之前得到的百度账号授权cookie中的stoken参数重新向服务器获得了一个属于百度贴吧自己的sotken。之后利用该sotken重定向到贴吧首页。获得该stoken的代码如下,将其封装为一个函数,函数参数为百度账号的授权cookie

def get_tieba_authcookies(passport_authcookies):

	# 获取授权cookie
	with open('auth_cookies.txt', 'r') as f:
		cookiesstr = f.read()
		auth_cookies = json.loads(cookiesstr)

	# 首次访问贴吧首页时会重定向到passprot.baidu.com
	tieba_url = 'https://tieba.baidu.com/index.html'
	tieba_r = requests.get(tieba_url, cookies=passport_authcookies, headers=config.headers['tieba_headers'],allow_redirects=False)
	# 提取cookie,添加到授权cookie中
	auth_cookies['TIEBA_USERTYPE'] = tieba_r.cookies['TIEBA_USERTYPE']

	# 获取重定向地址,此时为passport.baidu.com,访问改地址后会再次重定向
	pass_url = tieba_r.headers['Location']
	pass_r = requests.get(pass_url, headers=TieBa.passport_headers, cookies=passport_authcookies,
	allow_redirects=False)

	# 获取headers中的贴吧STOKEN,并设置进auth_cookie
	tieba_stoken_url = pass_r.headers['Location']
	tieba_stoken_r = requests.get(tieba_stoken_url, headers=config.headers['tieba_headers'], cookies=passport_authcookies,
	allow_redirects=False)
	STOKEN = re.search(r'STOKEN=(\w*[^;])', tieba_stoken_r.headers['Set-Cookie']).group(1)
	passport_authcookies['STOKEN'] = STOKEN

	return passport_authcookies


贴吧签到

当我们获取到贴吧的授权cookie后,利用它访问贴吧首页即可获取相关信息:
第一步: 访问贴吧首页地址https://tieba.baidu.com/index.html,获取我关注的贴吧列表。
访问首页时,我关注的贴吧列表如下图,默认只显示8个,超过8个时点击查看更多按钮,查看其他的列表。

python贴吧自动签到,解放你的双手_第6张图片

当点击查看更多按钮时,通过浏览器开发者模式追踪可以发现,浏览器没有发送任何请求,所以可以断定,关注的贴吧列表信息已经提前加载好了,我们的信息是通过js展示上去的。查看网页源码,可以找出相关信息,具体如下图。图中的is_sign字段就代表是否已经签到的信息。

通过正则表达式对贴吧列表信息进行提取,将其封装为一个函数:

def get_mytbdict(tieba_authcookies):
	tieba_url = 'https://tieba.baidu.com/index.html'
	# 读取百度账号的授权cookie
	with open('auth_cookies.txt', 'r') as f:
		passport_cookiesstr = f.read()
		passport_authcookies = json.loads(passport_cookiesstr)
		# 获取贴吧的授权cookie
		auth_cookies = get_tieba_authcookies(passport_authcookies)

	# 利用新token请求首页,获取关注的贴吧列表
	tieba_index_r = requests.get(tieba_url, cookies=auth_cookies,   headers=config.headers['tieba_headers'])
	content = tieba_index_r.text
	#正则表达式提取贴吧列表
	pattern = re.compile(r"{\"user_id\"[^}]*\"is_sign\":\d}")
	tbinfo_list = pattern.findall(content)

	# mytb存放贴吧信息,key是贴吧的ID,value是贴吧的名称
	mytb ={}
	for item in tbinfo_list:
	json_item = json.loads(item)
	forum_name = json_item['forum_name']
	forum_id = json_item['forum_id']
	mytb[forum_id]=forum_name

	return mytb

第二步: 随便进入一个未签到的贴吧,点击签到按钮,可以发现它发送了一个add请求。

python贴吧自动签到,解放你的双手_第7张图片
python贴吧自动签到,解放你的双手_第8张图片

这个请求有三个参数,一个是ie,这个是对响应内容采用的编码,一个是tbs,经测试,这个值可以固定,也可以从页面原码中获取,最后一个是kw,这个是贴吧名称。明确这些信息以后,就可以利用代码进行签到:

def auto_sign():
    mytb_names = list(get_mytbdict(auth_cookies).values())
    # 签到
    for tb_name in mytb_names:
        sign_url = 'https://tieba.baidu.com/sign/add'
        sign_data = {
            'ie': 'utf-8',
            'kw': tb_name,
            'tbs': '6868ce0283f2fb151561865643'
        }
        sign_res=requests.post(sign_url, data=sign_data, cookies=auth_cookies, headers=config.headers['tieba_headers'])
        print(sign_res.text)

完整代码

import config
import requests
import re
import json
import time
from pyquery import PyQuery as pq
# 获取毫秒级时间戳
def get_cur_timestamp():
    return int(round((time.time()) * 1000))

class TieBa:

    tieba_headers = config.headers['tieba_headers']
    passport_headers = config.headers['passport_headers']
    @staticmethod
    def auto_sign():
        with open('auth_cookies.txt', 'r') as f:
            cookiesstr = f.read()
            passport_authcookies = json.loads(cookiesstr)
            auth_cookies=TieBa.get_tieba_authcookies(passport_authcookies)

        mytb_names = list(TieBa.get_mytbdict(auth_cookies).values())
        # 签到
        for tb_name in mytb_names:
            sign_url = 'https://tieba.baidu.com/sign/add'
            sign_data = {
                'ie': 'utf-8',
                'kw': tb_name,
                'tbs': '6868ce0283f2fb151561865643'
            }
            sign_res=requests.post(sign_url, data=sign_data, cookies=auth_cookies, headers=config.headers['tieba_headers'])
            print(sign_res.text)

    @staticmethod
    def get_tieba_authcookies(passport_authcookies):

        # 获取授权cookie
        with open('auth_cookies.txt', 'r') as f:
            cookiesstr = f.read()
            auth_cookies = json.loads(cookiesstr)

        # 首次访问贴吧首页时会重定向到passprot.baidu.com
        tieba_url = 'https://tieba.baidu.com/index.html'
        tieba_r = requests.get(tieba_url, cookies=passport_authcookies, headers=TieBa.tieba_headers,allow_redirects=False)
        # 提取cookie,添加到授权cookie中
        auth_cookies['TIEBA_USERTYPE'] = tieba_r.cookies['TIEBA_USERTYPE']

        # 获取重定向地址,此时为passport.baidu.com,访问改地址后会再次重定向
        pass_url = tieba_r.headers['Location']
        pass_r = requests.get(pass_url, headers=TieBa.passport_headers, cookies=passport_authcookies,
                              allow_redirects=False)

        # 获取headers中的贴吧STOKEN,并设置进auth_cookie
        tieba_stoken_url = pass_r.headers['Location']
        tieba_stoken_r = requests.get(tieba_stoken_url, headers=TieBa.tieba_headers, cookies=passport_authcookies,
                                      allow_redirects=False)
        STOKEN = re.search(r'STOKEN=(\w*[^;])', tieba_stoken_r.headers['Set-Cookie']).group(1)
        passport_authcookies['STOKEN'] = STOKEN

        return passport_authcookies
    @staticmethod
    def get_mytbdict(tieba_authcookies):
        tieba_url = 'https://tieba.baidu.com/index.html'
        with open('auth_cookies.txt', 'r') as f:
            cookiesstr = f.read()
            passport_authcookies = json.loads(cookiesstr)
            auth_cookies = TieBa.get_tieba_authcookies(passport_authcookies)

        # 利用新token请求首页,获取关注的贴吧列表
        tieba_index_r = requests.get(tieba_url, cookies=auth_cookies, headers=config.headers['tieba_headers'])
        content = tieba_index_r.text
        pattern = re.compile(r"{\"user_id\"[^}]*\"is_sign\":\d}")
        tbinfo_list = pattern.findall(content)

        # 用set存放提取出的贴吧列表,防止重复
        mytb ={}
        for item in tbinfo_list:
            json_item = json.loads(item)
            forum_name = json_item['forum_name']
            forum_id = json_item['forum_id']
            mytb[forum_id]=forum_name

        return mytb

if __name__ == '__main__':
    TieBa.auto_sign()

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