Python项目:扇贝网小组查卡助手
扇贝网是一个非常棒的英语学习网站,大家还可以加入一些小组,一起交流学习、共同进步。但是,小组管理起来非常辛苦,尤其是在0点前踢出不打卡的成员,因此考虑利用程序来实现小组查卡自动化。
登录
操作 | 扇贝网登录 | |
URL | http://www.shanbay.com/accounts/login/ | |
方式 | POST | |
数据 | csrfmiddlewaretoken | CSRF令牌 |
username | 用户名 | |
password | 密码 |
CSRF令牌存在于Cookie中,我们需要先以GET方式访问该URL,就能取到CSRF令牌了。
- # -*- coding: utf-8 -*-
- import requests
- class Shanbay():
- def __init__(self, username, password):
- self.request = requests.Session()
- self.username = username
- self.password = password
- def login(self):
- url = 'http://www.shanbay.com/accounts/login/'
- 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 | http://www.shanbay.com/api/v1/team/member/ | |
方式 | PUT | |
数据 | action | 动作('dispel') |
ids | data-id |
- # -*- coding: utf-8 -*-
- from bs4 import BeautifulSoup
- from Journal import Journal
- import re
- class Domain():
- def __init__(self, shanbay):
- self.shanbay = shanbay
- self.request = shanbay.request
- def get_not_checked_members(self):
- '''
- data_id : 踢人时需要data_id
- role : 身份标识
- nickname : 昵称
- user_id : 发短信时需要user_id
- username : 用户名
- points : 贡献值
- days : 组龄
- rate : 打卡率
- checked_yesterday: 昨天是否打卡
- checked : 今天是否打卡
- off_dyas : 入组后最近连续未打卡天数
- '''
- members = []
- for page in range(1, 48):
- html = self.request.get('http://www.shanbay.com/team/manage/?t=checkin_today&page=%d' % page).text
- soup = 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:
- break
- days = 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 = 1
- else:
- 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:
- continue
- break
- return members
- def dismiss(self, data_ids):
- url = 'http://www.shanbay.com/api/v1/team/member/'
- 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 time
- class Journal():
- def __init__(self, shanbay, user_id):
- self.shanbay = shanbay
- self.request = shanbay.request
- self.user_id = user_id
- self.soup = self.__get_journal_soup()
- def __get_journal_soup(self):
- html = self.request.get('http://www.shanbay.com/checkin/user/%s/' % self.user_id).text
- return 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 | http://www.shanbay.com/api/v1/message/ | |
方式 | POST | |
数据 | recipient | 收件人(username) |
subject | 标题 | |
body | 内容 | |
csrfmiddlewaretoken | CSRF令牌 |
- # -*- coding: utf-8 -*-
- class Message():
- def __init__(self, shanbay):
- self.shanbay = shanbay
- self.request = shanbay.request
- def send_msg(self,recipient, subject, body):
- url = 'http://www.shanbay.com/api/v1/message/'
- data = {
- 'recipient': recipient,
- 'subject': subject,
- 'body': body,
- 'csrfmiddlewaretoken': self.request.cookies['csrftoken']
- }
- return self.request.post(url, data=data).ok
小组管理
操作 | 设定加组条件 | |
URL | http://www.shanbay.com/team/setqualification/{team_id} | |
方式 | POST | |
数据 | value | 天数 |
kind | 类型 | |
condition | 条件 | |
team | 小组id | |
csrfmiddlewaretoken | CSRF令牌 |
若需要在小组发帖或回帖,需要forum_id而不是小组id,而forum_id可以通过小组主页找到。
操作 | 发帖 | |
URL | http://www.shanbay.com/api/v1/forum/{forum_id}/thread/ | |
方式 | post | |
数据 | title | 标题 |
body | 内容 | |
csrfmiddlewaretoken | CSRF令牌 |
操作 | 回帖 | |
URL | http://www.shanbay.com/api/v1/forum/thread/{post_id}/post/ | |
方式 | POST | |
数据 | body | 内容 |
csrfmiddlewaretoken | CSRF令牌 |
- # -*- coding: utf-8 -*-
- from bs4 import BeautifulSoup
- class Team():
- def __init__(self, shanbay, team_id):
- self.shanbay = shanbay
- self.request = shanbay.request
- self.team_id = team_id
- self.forum_id = self.__get_forum_id()
- def set_join_limit(self, days, kind=2, condition='>='):
- url = 'http://www.shanbay.com/team/setqualification/%s' % self.team_id
- data = {
- 'value': days,
- 'kind': kind,
- 'condition': condition,
- 'team': self.team_id,
- 'csrfmiddlewaretoken': self.request.cookies['csrftoken']
- }
- r = self.request.post(url, data=data)
- return 'http://www.shanbay.com/referral/invite/?kind=team' == r.url
- def __get_forum_id(self):
- html = self.request.get('http://www.shanbay.com/team/detail/%s/' % str(self.teamId)).text
- soup = BeautifulSoup(html)
- return soup.find(id='forum_id')['value']
- def new_post(self, title, content):
- url = 'http://www.shanbay.com/api/v1/forum/%s/thread/' % self.forum_id
- data = {
- '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 = 'http://www.shanbay.com/api/v1/forum/thread/%s/post/' % post_id
- data = {
- 'body': content,
- 'csrfmiddlewaretoken': self.request.cookies.get('csrftoken')
- }
- return self.request.post(url, data=data).json()
Python项目:扇贝网小组查卡助手的更多相关文章
- Jenkins部署Python项目实战
一.背景 我们工作中常用Jenkins部署Java代码,因其灵活的插件特性,例如jdk,maven,ant等使得java项目编译后上线部署一气呵成,同样对于脚本语言类型如Python上线部署,利用Je ...
- 做中学(Learning by Doing)之背单词-扇贝网推荐
做中学(Learning by Doing)之背单词-扇贝网推荐 看完杨贵福老师(博客,知乎专栏,豆瓣)的「继续背单词,8个月过去了」,我就有写这篇文章的冲动了,杨老师说: 有时候我会感觉非常后悔,如 ...
- 以正确的方式开源 Python 项目
以正确的方式开源 Python 项目 大多数Python开发者至少都写过一个像工具.脚本.库或框架等对其他人也有用的工具.我写这篇文章的目的是让现有Python代码的开源过程尽可能清 晰和无痛.我不是 ...
- 创建成功的Python项目
创建成功的Python项目 前端开发工具技巧介绍—Sublime篇 SEO在网页制作中的应用 观察者模式 使用D3制作图表 英文原文:Create successful Python projects ...
- 以正确的方式开源 Python 项目(转)
大多数Python开发者至少都写过一个像工具.脚本.库或框架等对其他人也有用的工具.我写这篇文章的目的是让现有Python代码的开源过程尽可能清晰和无痛.我不是简单的指——“创建一个GitHub库,提 ...
- Python教程百度网盘哪里有?
Python为我们提供了非常完善的基础代码库,覆盖了网络.文件.GUI.数据库.文本等大量内容,被形象地称作"内置电池(batteries included)".带你快速入门的Py ...
- python爬虫实例--网易云音乐排行榜爬虫
网易云音乐,以前是有个api 链接的json下载的,现在没了, 只有音乐id,title , 只能看播放请求了, 但是播放请求都是加密的值,好坑... 进过各种努力, 终于找到了个大神写的博客,3.6 ...
- python项目开发视频
精品Python项目开发学习视频 所属网站分类: 资源下载 > python视频教程 作者:乐天派 链接:http://www.pythonheidong.com/blog/article/44 ...
- Docker如何部署Python项目
Docker 部署Python项目 作者:白宁超 2019年5月24日09:09:00 导读: 软件开发最大的麻烦事之一就是环境配置,操作系统设置,各种库和组件的安装.只有它们都正确,软件才能运行.如 ...
随机推荐
- 循序渐进Python3(十二) --1-- web框架之django
Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为: 大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能 ...
- 在table中进行内容搜索
$("tbody td").filter(":contains('" + x + "')").css('color','red').pare ...
- lucene写索引出现锁文件的原因之一
lucene正常情况目录下的文件 有三个文件. segments.gen segments_a08, 还有一个类似 _uw.cfs名字的东西. 当然,不一定都一样, 但肯定是这三个. 如果出现了很多文 ...
- poj 3692 Kindergarten (最大独立集)
Kindergarten Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4903 Accepted: 2387 Desc ...
- ios -网络加载json和本地加载json
1网络加载json的时候,要在模型的实现文件里写: - (void)setValue:(id)value forKey:(NSString *)key { } 2本地加载json的时候,要在模型的实现 ...
- Winfrom实现圆角设计
主要代码 public partial class Form1 : Form { public Form1() { InitializeComp ...
- code project 上的内存管理的示例代码
/******************************************************************** created: 2014/03/17 18:53 file ...
- ELK日志管理之——logstash配置语法
Logstash 设计了自己的 DSL -- 有点像 Puppet 的 DSL,或许因为都是用 Ruby 语言写的吧 -- 包括有区域,注释,数据类型(布尔值,字符串,数值,数组,哈希),条件判断,字 ...
- 将搜狗词库.scel格式转化为.txt格式
由于项目中要用到词库,而下载的搜狗词库是.scel格式,所以就用python脚本将搜狗词库.scel格式文件转化为.txt格式文件. #!/bin/python # -*- coding: utf-8 ...
- bootstrap的html模版
<!DOCTYPE html> <html> <head> <title>Bootstrap 模板</title> <meta nam ...