扇贝网小组查卡助手"/>
Python项目:扇贝网小组查卡助手
扇贝网是一个非常棒的英语学习网站,大家还可以加入一些小组,一起交流学习、共同进步。但是,小组管理起来非常辛苦,尤其是在0点前踢出不打卡的成员,因此考虑利用程序来实现小组查卡自动化。
登录
操作 | 扇贝网登录 | |
URL | / | |
方式 | POST | |
数据 | csrfmiddlewaretoken | CSRF令牌 |
username | 用户名 | |
password | 密码 |
CSRF令牌存在于Cookie中,我们需要先以GET方式访问该URL,就能取到CSRF令牌了。
# -*- coding: utf-8 -*- import requestsclass Shanbay():def __init__(self, username, password):self.request = requests.Session()self.username = usernameself.password = passworddef login(self):url = '/'r = self.request.get(url)csrftoken = r.cookies['csrftoken']data = {'csrfmiddlewaretoken': csrftoken,'username': self.username,'password': self.password,}return self.request.post(url, data=data).ok
成员管理
如果我们获取小组管理后台所有组员的信息,比较费时间。考虑实际需求,不妨仅获取当天未打卡的组员的信息,这样能大大提高查卡效率。
踢人需要data-id,这个在小组管理后台页面就能获取到。但是,如果我们想发站内短信,就需要username,而username在小组管理后台页面里是没有的,这个需要查看个人打卡日记。
从个人打卡日记不仅能看到username,还能看到该贝友入组后最近已连续有多少天未打卡(这往往也是组规限定的内容)等等。
操作 | 踢人 | |
URL | / | |
方式 | PUT | |
数据 | action | 动作('dispel') |
ids | data-id |
# -*- coding: utf-8 -*- from bs4 import BeautifulSoup from Journal import Journal import reclass Domain():def __init__(self, shanbay):self.shanbay = shanbayself.request = shanbay.requestdef get_not_checked_members(self):'''data_id : 踢人时需要data_idrole : 身份标识nickname : 昵称user_id : 发短信时需要user_idusername : 用户名points : 贡献值days : 组龄rate : 打卡率checked_yesterday: 昨天是否打卡checked : 今天是否打卡off_dyas : 入组后最近连续未打卡天数'''members = []for page in range(1, 48):html = self.request.get('/?t=checkin_today&page=%d' % page).textsoup = BeautifulSoup(html, 'html5lib')for member in soup.find_all('tr', class_='member'):checked = member.find_all(class_='checked')[1].find('span').text.strip() == '已打卡'if checked:breakdays = int(member.find(class_='days').text)user_id = re.findall('\d+', member.find(class_='user').find('a')['href'])[0]user = Journal(shanbay=self.shanbay, user_id=user_id)checked_yesterday = member.find_all(class_='checked')[0].find('span').text.strip() == '已打卡'if checked_yesterday:off_days = 1else:off_days = user.get_off_days(days)data = {'data_id':member['data-id'],'role':member['role'],'nickname':member.find(class_='user').find('a').text,'user_id':user_id,'username':user.get_username(),'points':int(member.find(class_='points').text),'days':days,'rate':float(member.find(class_='rate').find('span').text[:-2]),'checked_yesterday':checked_yesterday,'checked':checked,'off_dyas':off_days}members.append(data)else:continuebreakreturn membersdef dismiss(self, data_ids):url = '/'data = {'action': 'dispel',}data['ids'] = ','.join(map(str, data_ids))r = self.request.put(url, data=data)return r.json()['msg'] == "SUCCESS"
(这里用到了Python跳出两层循环的技巧*^_^*)
打卡日记
通过打卡日记,我们可以获得一些基本信息,例如:用户名、最近连续未打卡天数等。
# -*- coding: utf-8 -*-from bs4 import BeautifulSoup import re import datetime import timeclass Journal():def __init__(self, shanbay, user_id):self.shanbay = shanbayself.request = shanbay.requestself.user_id = user_idself.soup = self.__get_journal_soup()def __get_journal_soup(self):html = self.request.get('/%s/' % self.user_id).textreturn BeautifulSoup(html)def get_username(self):return re.findall(u'(\w+)\s*的日记', self.soup.find_all(class_='page-header')[0].find('h2').text)[0]def get_off_days(self, days=0):pass
站内短信
操作 | 发送站内短信 | |
URL | / | |
方式 | POST | |
数据 | recipient | 收件人(username) |
subject | 标题 | |
body | 内容 | |
csrfmiddlewaretoken | CSRF令牌 |
# -*- coding: utf-8 -*-class Message():def __init__(self, shanbay):self.shanbay = shanbayself.request = shanbay.requestdef send_msg(self,recipient, subject, body):url = '/'data = {'recipient': recipient,'subject': subject,'body': body,'csrfmiddlewaretoken': self.request.cookies['csrftoken']}return self.request.post(url, data=data).ok
小组管理
操作 | 设定加组条件 | |
URL | /{team_id} | |
方式 | POST | |
数据 | value | 天数 |
kind | 类型 | |
condition | 条件 | |
team | 小组id | |
csrfmiddlewaretoken | CSRF令牌 |
若需要在小组发帖或回帖,需要forum_id而不是小组id,而forum_id可以通过小组主页找到。
操作 | 发帖 | |
URL | /{forum_id}/thread/ | |
方式 | post | |
数据 | title | 标题 |
body | 内容 | |
csrfmiddlewaretoken | CSRF令牌 |
操作 | 回帖 | |
URL | /{post_id}/post/ | |
方式 | POST | |
数据 | body | 内容 |
csrfmiddlewaretoken | CSRF令牌 |
# -*- coding: utf-8 -*- from bs4 import BeautifulSoupclass Team():def __init__(self, shanbay, team_id):self.shanbay = shanbayself.request = shanbay.requestself.team_id = team_idself.forum_id = self.__get_forum_id()def set_join_limit(self, days, kind=2, condition='>='):url = '/%s' % self.team_iddata = {'value': days,'kind': kind,'condition': condition,'team': self.team_id,'csrfmiddlewaretoken': self.request.cookies['csrftoken']}r = self.request.post(url, data=data)return '/?kind=team' == r.urldef __get_forum_id(self):html = self.request.get('/%s/' % str(self.teamId)).textsoup = BeautifulSoup(html)return soup.find(id='forum_id')['value']def new_post(self, title, content):url = '/%s/thread/' % self.forum_iddata = {'title': title,'body': content,'csrfmiddlewaretoken': self.request.cookies['csrftoken']}return self.request.post(url, data=data).json()def reply_post(self, post_id, content):url = '/%s/post/' % post_iddata = {'body': content,'csrfmiddlewaretoken': self.request.cookies.get('csrftoken')}return self.request.post(url, data=data).json()
转载于:.html
更多推荐
Python项目:扇贝网小组查卡助手
发布评论