美文网首页
数据接口发现

数据接口发现

作者: __Cool | 来源:发表于2017-12-31 21:09 被阅读42次

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

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

    网上的接口大多收费,免费版本还需要申请,于是去这些网站做了简单的调试后,获得了几个 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 构造请求。

    相关文章

      网友评论

          本文标题:数据接口发现

          本文链接:https://www.haomeiwen.com/subject/mqnagxtx.html