zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    详细分析MySQL事务日志(redo log和undo log)
    详细分析MySQL的日志(一)
    MySQL/MariaDB中的事务和事务隔离级别
    详细介绍MySQL/MariaDB的锁
    MariaDB/MySQL用户和权限管理
    (MariaDB)开窗函数用法
    翻译:window function(已提交到MariaDB官方手册)
    翻译:group_concat()函数(已提交到MariaDB官方手册)
    (MariaDB/MySQL)之DML(1):数据插入
    (MariaDB/MySQL)MyISAM存储引擎读、写操作的优先级
  • 原文地址:https://www.cnblogs.com/wenjianmuran/p/5323161.html
Copyright © 2011-2022 走看看