Python project: scallop Network Group Card Checking assistant and python Card Checking
Scallop network is a great English learning website. You can join groups to exchange and learn and make progress together. However, it is very hard to manage the group, especially when the member is kicked out before. Therefore, the program is used to automate the inspection of the group card.
Login
Operation |
Log on to the scallop Network |
URL |
Http://www.shanbay.com/accounts/login/ |
Method |
POST |
Data |
Csrfmiddlewaretoken |
CSRF token |
Username |
User Name |
Password |
Password |
The CSRF token exists in the Cookie. You must first access the URL in GET mode to obtain the CSRF token.
# -*- coding: utf-8 -*-import requestsclass 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
Member Management
It takes a long time to obtain information about all team members in the group management background. Considering the actual needs, you may wish to obtain the information of the member who has not been punched in on the current day, which can greatly improve the Card Checking efficiency.
Data-id is required for the kicker, which can be obtained on the group management background page. However, if we want to send a text message on the site, we need username, which is not available on the group management background page. You need to check the personal punching diary.
From the personal punching diary, we can not only see the username, but also the number of days that the member has not been punched in (this is often the content defined by the group rules.
Operation |
Kicker |
URL |
Http://www.shanbay.com/api/v1/team/member/ |
Method |
PUT |
Data |
Action |
Action ('dispel ') |
Ids |
Data-id |
#-*-Coding: UTF-8-*-from bs4 import BeautifulSoupfrom Journal import Journalimport reclass Domain (): def _ init _ (self, shanbay): self. shanbay = shanbay self. request = shanbay. request def get_not_checked_members (self): ''' data_id: data_id role: Id nick name: nickname user_id: user_id username: userpoints: contribution value days: group age rate: Punch rate checked_yesterday: whether to punch in yesterday checked: whether to punch in today off_dyas: The number of consecutive days after Enrollment ''' 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 () = 'punched out '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 () = 'punched out '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 ['kids'] = ','. join (map (str, data_ids) r = self. request. put (url, data = data) return r. json () ['msg '] = "SUCCESS"
(The technique of jumping out of two loops in Python is used here * ^_^ *)
Punching Diary
Through the punching diary, we can obtain some basic information, such as the user name and the number of consecutive days without punching in.
#-*-Coding: UTF-8-*-from bs4 import BeautifulSoupimport reimport datetimeimport timeclass 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/ss/' % self. user_id ). text return BeautifulSoup (html) def get_username (self): return re. findall (U' (\ w +) \ s * diary ', self. soup. find_all (class _ = 'page-header') [0]. find ('h2 '). text) [0] def get_off_days (self, days = 0): date_arr = [] for a in self. soup. find_all (class _ = 'target'): mon, day, year = re. findall (U' (\ S +) month \ s * (\ d +) \ s *, \ s * (\ d +) ',. text) [0] mon = mon. replace ('11', '11 '). replace ('12', '12 '). replace ('1', '1 '). replace ('2', '2 '). replace ('3', '3 '). replace ('4', '4 '). replace ('5', '5 '). replace ('6', '6 '). replace ('7', '7 '). replace ('8', '8 '). replace ('9', '9 '). replace ('10', '10') date_arr.append (datetime. datetime (* (time. strptime ('-'. join (year, mon, day), '% Y-% m-% D') [: 3]) today = datetime. datetime (* (time. localtime () [: 3]) for day in range (0, days): if today-datetime. timedelta (days = day) in date_arr: return day return days
Intra-site SMS
Operation |
Intra-site SMS |
URL |
Http://www.shanbay.com/api/v1/message/ |
Method |
POST |
Data |
Recipient |
Recipient (username) |
Subject |
Title |
Body |
Content |
Csrfmiddlewaretoken |
CSRF token |
# -*- 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
Group Management
Operation |
Set adding group conditions |
URL |
Http://www.shanbay.com/team/setqualification/?team_id} |
Method |
POST |
Data |
Value |
Days |
Kind |
Type |
Condition |
Condition |
Team |
Group id |
Csrfmiddlewaretoken |
CSRF token |
To post or reply to a group, You Need To forum_id instead of the group id, and forum_id can be found on the group homepage.
Operation |
Post |
URL |
Http://www.shanbay.com/api/v1/forum/#forum_id#/thread/ |
Method |
Post |
Data |
Title |
Title |
Body |
Content |
Csrfmiddlewaretoken |
CSRF token |
Operation |
Reply |
URL |
Http://www.shanbay.com/api/v1/forum/thread/?post_id=/post/ |
Method |
POST |
Data |
Body |
Content |
Csrfmiddlewaretoken |
CSRF token |
# -*- coding: utf-8 -*-from bs4 import BeautifulSoupclass 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()