数据接口发现

微信公众号机器人项目练习,目前功能有:

  • 四六级
  • 快递
  • 天气
  • 电影票房
  • 通识课题目

网上的接口大多收费,免费版本还需要申请,于是去这些网站做了简单的调试后,获得了几个 url 查询伪接口。

使用到的库:

作用
urllib quote 方法对中文编码
requests 仿浏览器发起请求
Beautifulsoup 解析表单
json 处理服务器的 response 数据

1、四六级接口

四六级查询有两个官方查询网址,中国教育考试网和中国高等教育学生信息网(学信网),学信网的验证方式较为简单,反应较快,此次调试选择学信网

调试过程:

  1. 构造 headers 包括 user-agentreferer(缺少 referer 则查询失败)
  2. 需要提交的表单有 zkzh(准考证号)、xm(姓名)
  3. 返回成功的数据采用 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 。

调试过程:

  1. 通过快递单号获取到快递公司名称,返回 json 格式的数据
  2. 用 json 库解析数据,筛选公司名称
  3. 再将快递单号公司名称用 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、电影票房查询

各大门户都有相关的电影票房信息,在这选择调试中国票房

调试过程:

  1. 将当前时间发送至相关 url ,返回 json 格式数据
  2. 解析 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,官网注册后可获得一些免费天气调用次数。

调试过程:

  1. 不同的天气信息有不同的 api
  2. 官方有相关 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、通识课查询

来源于考试资料网

调试过程:

  1. 该网站对将要查询题目用 js 进行加密
  2. 查询成功后,答案也进行了相关加密
  3. 分两次访问,第一次请求服务器获得题目url,第二次请求题目url获取答案
  4. 查询一道题目需要访问两次该网站,有点耗时
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 构造请求。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,024评论 4 62
  • 下一篇 Framework--怎么使用Framework 1、什么是Framework? Framework是资...
    慧惠阅读 3,009评论 0 5
  • 最近赶项目,一周上7天班每天还得搞到十点十一点,实在是没有精力再看书了。但是写项目的时候碰到的一个Bug完全超出了...
    CoderMageFox阅读 2,591评论 1 3
  • service保活 在实际开发中,我们会遇到一些要求后台运行的service,但是现在Android手机型号太多,...
    北方的天空2000阅读 1,784评论 0 5