首頁>技術>

前言

最近想從圖書館裡借一本書,可是圖書館裡那兩本書都借走了,其中有一本書在3月3號到期應還,所以我想著這幾天那個人應該會來圖書館還書,所以我寫了個python指令碼,放在伺服器上,每隔一段時間查詢,如果那人還書了,郵件通知我。這樣我就可以及時借書了,哈哈。

使用的工具:

谷歌瀏覽器;Python3.8 ,雲linux伺服器

所需知識:

瀏覽器開發者工具的基本使用;http get請求;json處理;smtp郵件傳送;linux伺服器crontab的使用

分析web頁面

判斷資料載入方式

找到需要分析的web頁面,開啟瀏覽器的開發者工具,重新整理。

這是我學校圖書館網址:圖書館書籍查詢

上圖展示的是我要查詢的書(《tensorflow從零開始學》),第二個標註的是書的存在狀態。

頁面有了,於是開始分析這些資訊是怎麼來的。

幸運的是,書的存在狀態是網頁透過AJAX獲取的json來載入資訊。下一標題會展示我是怎麼找資料的。分析json資訊即可得到所需資料(因為資料是後來載入的,可以先把網頁下載下來,看看有沒有資訊,沒有的話,就是後期js獲取的)

如果伺服器直接返回的頁面直接包含所需資料,那就比較麻煩了,需要分析html頁面,不過也簡單,以前用java的jsoup工具分析html比較好用,Python應該也有處理html的庫,初學python,不大熟悉。

迴歸正題

js獲取的內容可以在谷歌瀏覽器的開發者面板裡,找到Network,再選擇XHR。如下圖

列表裡展示的是這個頁面所有的js請求

分析js請求

透過枯燥乏味的尋找(一定要耐心尋找,這是最耗時間的地方),我終於找到一個請求,裡面是json資訊,如下圖

可以看到第四個js請求中返回的是json資料,json資料中有我需要的資訊

分析http請求

切換到header選項,如下圖

你會發現請求方式為Get請求,引數為如下圖所示

一看就知道bookrecnos為請求書目的id,想查什麼數目就加上數目id引數

然後返回的是json格式資料,我把json資料複製到csdn的json解析工具裡(什麼json解析工具無所謂。我只是為了方便看json資訊,我用的是CSDN外掛中json工具,使用方便一些),如下圖

左側為原本資料,右側為json工具處理的,是不是清爽了許多?

分析json資料

可以看到key為previews裡面有書籍資訊,我們要查詢的數目id為1901457577

1901457577裡面有多組資訊,因為我們學校有多個校區,所以展示的是多個校區的查詢結果,我們只要青島校區的資料,資料如下:

"1901445771":

{

"bookrecno": 1901445771,

"callno": "TP183/147",

"curlib": "01000",

"curlibName": "青島校區",

"curlocal": "QZKK",

"curlocalName": "青島自科書庫",

"copycount": 2,

"loanableCount": 0,

"shelfno": null,

"barcode": "4634944"

},

copycount為總共的書的存量

loanableCount為剩餘書的存量

現在已經知道json的資料存放位置,下面開始進行寫python指令碼

編寫Python指令碼

我自學的第一門語言是java,其實java也可以,但是由於在學深度學習,現在以後主要學習python,所以這次我嘗試使用Python工具來編寫指令碼

匯入需要的庫

import requests

import json

import smtplib

import datetime

from email.mime.text import MIMEText

from email.header import Header

這些庫都是平常使用的,requests庫用來發送get請求,json庫來解析json資料,smtplib來進行資料傳送。email路用來編寫郵件內容

傳送get請求

#要查詢的數目id

id=["1901457577"]#可以為多個數目,我只想查詢一個書

#引數params為字典型別,“bookrecnos”為查詢的數目id,想查詢多個數目的話,以逗號隔開(這裡只想查詢一個書)

params={"bookrecnos":id,"return_fmt":"json"}

response=requests.get("http://interlib.sdust.edu.cn/opac/book/holdingPreviews",params=params)

使用requests.get()傳送get請求

解析json

使用json.loads()方法返回的是字典,

JSON 解碼為 Python 型別轉換對應表:

json=json.loads(response.text)

#previews是字典,裡面key為剛才查詢引數帶的書的id

preview=json["previews"]

#要id為1901457577的數目

book_info=preview[id[0]]

#從book_info列表中挑選含有“青島校區”的字典

book={}

for i in book_info:

school=i["curlibName"]

if school== "青島校區":

book=i

break #如果找到 青島校區,直接跳出迴圈

count=book["copycount"]#共有幾本書

remainCount=book["loanableCount"]#剩餘幾本書

smtp傳送郵件

我用的163郵箱傳送到我的qq郵箱,

你需要在163郵箱中申請一個授權碼,獲取授權碼的方式可以百度一下,這裡不做敘述

#如果有書,則傳送郵件通知我

if count>0 and remainCount==0:

message="id為{0}的書,現有{1}本,總共有{2}本,當前時間:{3}".format(id[0],remainCount,count,datetime.datetime.now())

print(message)

# 第三方 SMTP 服務

mail_host="smtp.163.com" #設定伺服器

mail_user="[email protected]" #使用者名稱,你想使用什麼郵箱傳送資訊

mail_pass="XXXXXXXXXXX" #口令,郵箱授權碼

sender = '[email protected]'

receivers = ['[email protected]'] # 接收郵件,可設定為你的QQ郵箱或者其他郵箱

mess = MIMEText(message, 'plain', 'utf-8')

subject = "圖書查詢結果"

mess['Subject'] = Header(subject, 'utf-8')

mess['From'] = sender

mess['To'] =receivers[0]

smtp = smtplib.SMTP_SSL(mail_host, 994)

try:

smtp.login(mail_user,mail_pass)

smtp.sendmail(sender, receivers, mess.as_string())

print ("郵件傳送成功")

except smtplib.SMTPException as e:

print ("Error: 無法傳送郵件")

print(e)

finally :

smtp.close

else:

print("沒有剩餘的書了")

print("程式執行完成...")

注意:

from 和to一定要這麼寫:

mess['From'] = sender

mess['To'] =receivers[0]

1

2

不然會被163判斷為垃圾郵件,發不出去。

使用SMTP_SSL

smtp = smtplib.SMTP_SSL(mail_host, 994)

1

其實本來我寫的是smtp = smtplib.SMTP(mail_host, 25)

windows下編寫的時候能用,但是我放到伺服器執行不能用,可能是伺服器埠的問題吧。使用SMTP_SSL()萬無一失。

這是我寫的指令碼檔案,可以下載。

bookSearch.py

雲伺服器執行

將.py檔案上傳至伺服器

設定linux中crontab定時任務

使用crontab -e來編輯定時任務

crontab -e

1

*/10 8-22 * * * python3 /data/python_proj/library/bookSearch.py

1

我設定的是8點至22點,每10分鐘發查詢一次

crontab的具體使用可以參考這篇文章:Linux crontab命令的使用方法

然後重啟crontab服務就可以了

總結

7
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Git使用以及基本操作