Python Requests類比登入實現圖書館座位自動預約

來源:互聯網
上載者:User
這篇文章主要為大家詳細介紹了Python Requests的類比登入,Python實現圖書館座位自動預約,具有一定的參考價值,感興趣的小夥伴們可以參考一下

本文執行個體為大家分享了Python實現圖書館座位自動預約的具體代碼,供大家參考,具體內容如下

配置

通過公網主機定時運行指令碼,並發送郵件到自己的qq郵箱,這樣在就會有訊息提示是否預約成功

vim /etc/crontab

設定每到早上7:01自動運行指令碼即可

程式流程

(以yuyue.juneberry.cn網站為例)

  • get訪問登入頁面,擷取cookie和表單裡面的隱藏post欄位

  • 構造登入post資料,加入從表單裡面拿到的隱藏post欄位

  • post構造後的資料,類比登入,啟用cookie(使cookie有登入許可權)

  • get訪問座位預約介面,啟用cookie(使cookie有預約座位許可權)

  • post預約請求,實現預約座位

  • 解析返回結果,判斷是否成功,並寄件提醒

要點

  • requests庫中的requests.session() 能夠建立可傳遞cookies的會話

  • 拿到<input type=hidden>的資料並傳遞到post的資料中

  • 抓包判斷網站邏輯,篩選出各個請求的參數,並在程式中實現

函數解釋

  • class FUCK()主類

  • _get_date_str(self):擷取當前日期,並加上一天,用這個函數構造url的特徵欄位(圖書館設定提前一天預約座位)

  • def _get_order_url(self):構造"預約座位"的post目標url

  • def _get_static_post_attr:這個函數解析get請求的返回頁面,並從中提取出<input type=hidden>的欄位,用於之後的構造post資料

  • def login(self):實現登入功能

  • def run(self):實現座位預約功能

  • def _is_success(self, text):判斷預約結果

  • def error_log_once(self, text='default error (once)'):

  • def error_log(self, text='default error'):這兩個函數設定程式狀態為"已經出錯"或者"未出錯"狀態(用於自動化啟動並執行時候避免將重複的錯誤資訊寫入日誌)

  • def error_log(self, text='default error'):單次將錯誤資訊寫入本地日誌

  • sendmail.send_mail()郵件發送模組

代碼及注釋

# /bin/python# -*- coding:utf-8 -*-import timeimport sysimport requestsfrom bs4 import BeautifulSoupfrom mail import sendmail__author__ = 'xy'# 主類class FUCK(): def __init__(self, username, password, seatNO, mailto): """  以四個參數初始化,使用者名稱,密碼,要預約的座位號,接受預約結果提醒郵件的郵箱 """  self.username = username  self.password = password  self.seatNO = seatNO  self.mailto = mailto  self.base_url = 'http://yuyue.juneberry.cn'  self.login_url = 'http://yuyue.juneberry.cn'  self.order_url = self._get_order_url()  self.login_content = ''  self.middle_content = ''  self.final_content = ''  self.s = requests.session() # 建立可傳遞cookies的會話  # post data for login  self.data1 = {   'subCmd': 'Login',   'txt_LoginID': self.username, # S+學號   'txt_Password': self.password, # 密碼   'selSchool': 60, # 60表示北京交通大學  }  # post data for order a seat  self.data2 = {   'subCmd': 'query',  }  # 自訂http頭,然而我在程式裡並沒有使用  self.headers = {   'Connection': 'keep-alive',   'Content-Type': 'application/x-www-form-urlencoded',  }  self.login()  self.run()  self._is_success(self.final_content)  # 懷疑程式出錯時,取消下行注釋,可列印一些參數  # self._debug() def _get_date_str(self):  s = time.localtime(time.time())  ########333  date_str = str(s.tm_year) + '%2f' + str(s.tm_mon) + '%2f' + str(s.tm_mday + 1)  date_str = date_str.replace('%2f1%2f32', '%2f2%2f1') \   .replace('%2f2%2f29', '%2f3%2f1') \   .replace('%2f3%2f32', '%2f4%2f1') \   .replace('%2f4%2f31', '%2f5%2f1') \   .replace('%2f5%2f32', '%2f6%2f1') \   .replace('%2f6%2f31', '%2f7%2f1') \   .replace('%2f7%2f32', '%2f8%2f1') \   .replace('%2f8%2f32', '%2f9%2f1') \   .replace('%2f9%2f31', '%2f10%2f1') \   .replace('%2f10%2f32', '%2f11%2f1') \   .replace('%2f11%2f31', '%2f12%2f1') \   .replace('%2f12%2f32', '%2f1%2f1')  return date_str def _get_order_url(self):  return "http://yuyue.juneberry.cn/BookSeat/BookSeatMessage.aspx?seatNo=101001" + self.seatNO + "&seatShortNo=01" + self.seatNO + "&roomNo=101001&date=" + self._get_date_str() def _get_static_post_attr(self, page_content, data_dict):  """  拿到<input type='hidden'>的post參數,並添加到post_data中  """  soup = BeautifulSoup(page_content, "html.parser")  for each in soup.find_all('input'):   if 'value' in each.attrs and 'name' in each.attrs:    data_dict[each['name']] = each['value'] # 添加到login的post_data中    # self.data2[each['name']] = each['value'] # 添加到order的post_data中  return data_dict def _debug(self):  print self.order_url  print self.data1  print self.data2  print self.headers  print self.s.cookies  # print self.login_content  # print self.middle_content  print self.final_content def login(self):  homepage_content = self.s.get(self.base_url).content  self.data1 = self._get_static_post_attr(homepage_content, self.data1)  r = self.s.post(self.login_url, self.data1)  self.login_content = r.content def run(self):  # 這個get的意思是:原先的cookie沒有預約許可權,  # 訪問這個get之後,會使cookie擁有預約許可權,從而執行下一個post  self.middle_content = self.s.get('http://yuyue.juneberry.cn/BookSeat/BookSeatListForm.aspx').content  # 經測試,這個post只需要一個subCmd的參數就可以正常返回,因此不必根據get內容更新post參數  # self.data2 = self._get_static_post_attr(middle_content, self.data2)  # 這個post請求完成了預約功能!  r = self.s.post(self.order_url, self.data2)  self.final_content = r.content def _is_success(self, text):  """  接受最終的html內容,判斷是否成功,並觸發日誌記錄和寄件提醒  """  if '<h5 id="MessageTip">已經存在有效預約記錄。</h5>' in text:   self.clear_error_once('[done!] You already ordered a seat!')  elif '<h5 id="MessageTip">選擇的日期不允許預約。</h5>' in text:   self.clear_error_once('[done!] Date is wrong!')  elif '<h5 id="MessageTip">所選座位已經被預約。</h5>' in text:   self.clear_error_once('[done!] This seat is not available, maybe taken by others!')  elif '<h5 id="MessageTip">座位預約成功' in text:   self.clear_error_once('[done!] Success! An email is sending to you!')   sendmail.send_mail('BJTU Library Seat_NO:' + self.seatNO + 'ordered!',        'Sending by robot. Do not reply this mail!', self.mailto)  else:   self.error_log_once('Error! 302 to login page') def error_log_once(self, text='default error (once)'):  try:   is_error_file = open('./isopen_xy.txt', 'r')  except:   is_error_file = open('./isopen_xy.txt', 'w')  if '1' not in is_error_file.read():   print 'writting error to log...'   self.error_log(text)  else:   print 'already written to log'  is_error_file.close()  sendmail.send_mail('BJTU_Library system error once !', 'error text!') def error_log(self, text='default error'):  is_error_file = open('./isopen_xy.txt', 'w')  is_error_file.write('1\n')  is_error_file.close()  f = open("./log_xy.txt", 'a')  f.write(time.strftime("%Y-%m-%d %X", time.localtime()) + text + '\n')  f.close() def clear_error_once(self, text='success'):  print text  is_error_file = open('./isopen_xy.txt', 'w')  is_error_file.write('0\n')  is_error_file.close()if __name__ == '__main__': if len(sys.argv) < 5:  print 'Usage: python library.py [username] [password] [seat_NO] [email]'  print 'eg. python library.py S13280001 123456 003 XXXX@qq.com\n'  print 'Any problems, mail to: i[at]cdxy.me'  print '#-*- Edit by cdxy 16.03.24 -*-'  sys.exit(0) else:  FUCK(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.