微信公眾號機器人項目練習,目前功能有:
- 四六級
- 快遞
- 天氣
- 電影票房
- 通識課題目
網上的接口大多收費,免費版本還需要申請,于是去這些網站做了簡單的調試后,獲得了幾個 url 查詢偽接口。
使用到的庫:
庫 | 作用 |
---|---|
urllib | quote 方法對中文編碼 |
requests | 仿瀏覽器發起請求 |
Beautifulsoup | 解析表單 |
json | 處理服務器的 response 數據 |
1、四六級接口
四六級查詢有兩個官方查詢網址,中國教育考試網和中國高等教育學生信息網(學信網),學信網的驗證方式較為簡單,反應較快,此次調試選擇學信網。
調試過程:
- 構造
headers
包括user-agent
和referer
(缺少 referer 則查詢失敗) - 需要提交的表單有 zkzh(準考證號)、xm(姓名)
- 返回成功的數據采用
Beautifulsoup
解析相關信息
import urllib
import requests
from bs4 import BeautifulSoup
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.3397.16 Safari/537.36',
"Referer": "http://www.chsi.com.cn/cet/",
}
def get_grade(name, number):
try: # 姓名和學號可以互換
int(number)
except Exception as e:
# print(e)
name,number = number,name
name = urllib.quote(name)
# 構造url相關信息,用get發起請求
response = requests.get(
"http://www.chsi.com.cn/cet/query?zkzh={}&xm={}".format(number, name),
headers=headers, allow_redirects=False)
# 對返回的頁面進行解析
soup = BeautifulSoup(response.text, "html.parser")
infos = soup.select("table.cetTable td")
message = u""
message += u"姓名:" + infos[0].get_text().strip() + "\n"
message += u"學校:" + infos[1].get_text().strip() + "\n"
message += u"考試級別:" + infos[2].get_text().strip() + "\n"
message += u"準考證號:" + infos[3].get_text().strip() + "\n"
message += u"筆試成績" + "\n"
message += u"總分:" + infos[4].get_text().strip() + "\n"
message += u"聽力:" + infos[6].get_text().strip() + "\n"
message += u"閱讀:" + infos[8].get_text().strip() + "\n"
message += u"寫作和翻譯:" + infos[10].get_text().strip() + "\n"
message += u"口試成績" + "\n"
message += u"準考證號:" + infos[11].get_text().strip() + "\n"
message += u"等級:" + infos[12].get_text().strip() + "\n"
print(message)
return message
get_grade("準考證號","姓名")
返回信息:
姓名:李四
學校:XX大學
考試級別:英語六級
準考證號:111111112222222
筆試成績
總分:499
聽力:222
閱讀:150
寫作和翻譯:127
口試成績
準考證號:--
等級:--
2、快遞查詢
接口來源,快遞 100 。
調試過程:
- 通過快遞單號獲取到快遞公司名稱,返回
json
格式的數據 - 用 json 庫解析數據,篩選公司名稱
- 再將
快遞單號
和公司名稱
用 get 方法獲得快遞信息
import requests
import json
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.3397.16 Safari/537.36',
}
def get_company(number): # 根據單號獲取快遞公司名稱
response = requests.get("http://www.kuaidi100.com/autonumber/autoComNum?resultv2=1&text={}".format(str(number)),
headers=headers, )
result = json.loads(response.text)
company_result = result["auto"][0]["comCode"]
return company_result, number
def get_state(number): # 查詢快遞狀態
args = get_company(number)
response = requests.get("http://www.kuaidi100.com/query?type={}&postid={}".format(args[0], args[1]),
headers=headers)
result = json.loads(response.text)
print(result)
message = ""
for info in result["data"]:
message += info.get("ftime", "") + info.get("context", "") + "\n"
print(message)
return message
get_state("71182629191986")
返回信息:
·······
2017-10-14 21:00:56寧波市|發件|寧波市【寧波轉運中心】,正發往【金華轉運中心】
2017-10-14 20:00:12寧波市|到件|到寧波市【寧波轉運中心】
2017-10-14 13:43:55寧波市|收件|寧波市【寧波北侖】,【菜鳥上善/86103085】已攬收
3、電影票房查詢
各大門戶都有相關的電影票房信息,在這選擇調試中國票房 。
調試過程:
- 將當前時間發送至相關 url ,返回 json 格式數據
- 解析 json 數據即可
import requests
import json
import time
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.3397.16 Safari/537.36',
}
def get_movie():
now_time = str(int(time.time()*1000))
response = requests.get("http://www.cbooo.cn/BoxOffice/GetHourBoxOffice?d={}".format(now_time), headers=headers)
data = json.loads(response.text)
sum_box = u"今日總票房:" + data["data1"][0].get("sumBoxOffice", "") + u"萬 " + u" (每五分鐘更新)\n"
form = ""
for movie_detail in data["data2"][0:10]:
form += movie_detail["Irank"] + u"、" + movie_detail["MovieName"] + " "
form += u"實時票房:" + movie_detail["BoxOffice"] + u"萬 "
form += u"票房占比:" + movie_detail["boxPer"] + u"% "
form += u"上映天數:" + movie_detail["movieDay"] + u"天 "
form += u"累計票房:" + movie_detail["BoxOffice"] + u"萬 "
form += u"實時票房:" + movie_detail["sumBoxOffice"] + u"萬\n"
print(sum_box + form)
return sum_box + form
get_movie()
前 10 位票房信息:
今日總票房:1181.8萬 (每五分鐘更新)
1、王牌特工2:黃金圈 實時票房:340.92萬 票房占比:28.85% 上映天數:7天 累計票房:340.92萬 實時票房:34148.57萬
2、常在你左右 實時票房:235.56萬 票房占比:19.93% 上映天數:0天 累計票房:235.56萬 實時票房:252.06萬
3、羞羞的鐵拳 實時票房:142.22萬 票房占比:12.03% 上映天數:27天 累計票房:142.22萬 實時票房:207534.35萬
····
4、天氣查詢
來源:心知天氣 api,官網注冊后可獲得一些免費天氣調用次數。
調試過程:
- 不同的天氣信息有不同的 api
- 官方有相關 demo
import requests
import json
from pypinyin import lazy_pinyin
KEY = 'your api' # API key
UID = "your id" # 用戶ID
Daily_API = 'https://api.seniverse.com/v3/weather/daily.json' # API URL,可替換為其他 URL
UNIT = 'c' # 單位
LANGUAGE = 'zh-Hans' # 查詢結果的返回語言
def fetchWeather(location):
daily_result = requests.get(Daily_API, params={
'key': KEY,
'location': location,
'language': LANGUAGE,
'unit': UNIT
})
return daily_result.text
def get_Weather(city):
message = ""
all_result = fetchWeather(city)
suggestion = json.loads(all_result[0])
daily = json.loads(all_result[1])
message += u"地點:" + daily["results"][0]["location"]["name"] + "\n"
message += u"日期:" + daily["results"][0]["daily"][0]["date"] + "\n"
message += u"白天天氣:" + daily["results"][0]["daily"][0]["text_day"] + "\n"
# ····
print(message)
return message
get_Weather("shanghai") # 上海的拼音,相關拼音轉換可搜索相關庫
返回信息:
地點:上海
日期:2017-10-26
白天天氣:陰
···
5、通識課查詢
來源于考試資料網。
調試過程:
- 該網站對將要查詢題目用 js 進行加密
- 查詢成功后,答案也進行了相關加密
- 分兩次訪問,第一次請求服務器獲得題目url,第二次請求題目url獲取答案
- 查詢一道題目需要訪問兩次該網站,有點耗時
import re
import requests
import urllib
from bs4 import BeautifulSoup
import json
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.3397.16 Safari/537.36',
}
def utf8_decode(utf_text): # 對題目進行加密,查看js代碼寫出python版
string1 = ""
i1 = 0
while i1 < len(utf_text):
c = ord(utf_text[i1])
if c < 128:
string1 += chr(c)
i1 = i1 + 1
elif 191 < c < 224:
c2 = ord(utf_text[i1 + 1])
string1 += chr(((c & 31) << 6) | (c2 & 63))
i1 = i1 + 2
else:
c2 = ord(utf_text[i1 + 1])
c3 = ord(utf_text[i1 + 2])
string1 += chr(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))
i1 = i1 + 3
# print(string1)
return string1
def decode_result(encoded_text): # 對返回的答案進行解密,查看js代碼寫出python版
text = encoded_text
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
i = 0
output1 = ""
input1 = re.sub(r'[^A-Za-z0-9+/=]', "", text, re.S)
while i < len(input1):
enc1 = _keyStr.index(input1[i])
i = i + 1
enc2 = _keyStr.index(input1[i])
i = i + 1
enc3 = _keyStr.index(input1[i])
i = i + 1
enc4 = _keyStr.index(input1[i])
i = i + 1
chr1 = (enc1 << 2) | (enc2 >> 4)
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2)
chr3 = ((enc3 & 3) << 6) | enc4
output1 = output1 + chr(chr1)
if enc3 != 64:
output1 = output1 + chr(chr2)
if enc4 != 64:
output1 = output1 + chr(chr3)
output1 = utf8_decode(output1)
if "tiku/shiti" in output1:
number = re.match(r".*?(\d+).*", output1)
return number.group(1)
else:
raise Exception("無法查詢此題目")
def get_question(question): # 題目編碼后向服務器獲取題目答案地址,地址在返回的 json 中
trans = urllib.parse.quote(question.encode("gb2312"))
url = "https://data.api.ppkao.com/Interface/UserQueryApi.ashx?action=GetUserQueryWord&word={}&page=1".format(trans)
response = requests.get(url, headers=headers)
text = json.loads(response.text[13:-1])
link_code = text["UserQueryList"][0].get("urlPC", "")
if link_code is "":
link_code = text["UserQueryList"][0].get("urlApp", "")
return link_code
def get_answer(id): # 最后解析題目答案
url = "http://user.ppkao.com/mnkc/tiku/?id={}".format(id)
response = requests.get(url, headers)
soup = BeautifulSoup(response.text, "lxml")
obj = re.search(r".*查看答案!(.*)進入題庫.*", soup.text, re.S)
# print(obj.group(1).strip())
bb = ""
for aw in obj.group(1).strip().split("\n"):
if aw:
bb += aw + "\n"
print(bb)
# print(obj.group(1).strip())
return bb
def final_get_answer(question):
abc = get_question(question)
defg = decode_result(abc)
return get_answer(defg)
final_get_answer("冥王星與其他大行星迥異的特點不包括")
返回答案:
單項選擇題
冥王星與其他大行星迥異的特點不包括()。
A、公轉軌道平面偏角較大?
B、未清空軌道附近其他天體?
C、體積比一些衛星還小?
D、太陽位于其軌道的一個焦點上
參考答案:D
寫在后面
在這五個功能中,較難的是通識課的調試,需要涉及到 js 代碼、加解密等 ,其他幾個調試較為容易,將 json 數據轉成 python 的字典、用 requests 構造請求。