zoukankan      html  css  js  c++  java
  • python 百度API 获取地址IP

    在网络编程中,我们会和API打交道。那么,什么是API?如何使用API呢?本文分享了一下我对API的理解以及百度地图API的使用。

    API是"Application Programming Interface(应用程序编程接口)"的缩写。如果那一大堆的术语和定义让你头晕,不妨试着这样理解:网络服务商(比如百度、微博等)存有大量数据,我们可以查询数据,但是需要按照一定的格式/协议,否则服务商不知道我们的需求无法进行处理,我们拿到数据也看不懂。通过API接口规范,通信双方都能明白对方传送的信息和数据,同时也简化了操作(只要按照规定的格式输入,就可以得到已知格式的输出,我们无需了解具体实现的技术细节,是不是很省心呢?)

    下面以百度地图Web服务API的调用为例。

    要使用的是图中所示“正/逆地理编码服务”。在使用服务前,需要登录百度账号(如果没有就注册一个),申请成为百度开发者,然后创建一个你自己的应用,就可以收到一个对应的服务密钥(AK)。在服务配置页面,有两种校验方式,一种是IP白名单方式,一种是sn校验方式。我参考文章
    python实现百度地图API获取某地址的经纬度选择了sn校验方式,这样页面上会有SK。请将AK和SK两个序列码保存好,这就是你个人的验证信息。下一步使用百度地图API时要用到。
    要编写的这个python小程序实现的功能是:输入某个地址,得到相应的经纬度坐标信息。分三步实现。1、生成url(用于提交到API进行查询)2、与API交互,查询并返回数据(json格式) 3、利用json解析并输出。

    下面分别介绍具体实现。
    1、sn码及url的生成
    url= http://api.map.baidu.com/geocoder/v2/?address=“输入的地点名”&output=json&ak='你的AK码'&sn='你的sn码'。
    需要注意的是:

    • 由于url中有中文字符串,需要使用函数urllib.parse.quote(inputstr, safe="/:=&?#+!$,;'@()*[]")转换一下编码。
    • 在url里output可以选择输出为json格式或xml格式,默认是xml格式。
      import urllib.request,urllib.parse,urllib.error
      import json
      import hashlib
      
      MyAK='这里请填入你的AK'
      MySK='这里请填入你的SK'
      
      while True:
          address = input('输入地点:')
          if len(address)<1:
              break
      
          #产生sn码
          queryStr="/geocoder/v2/?address="+address+'&output=json&ak='+MyAK
          encodedStr=urllib.parse.quote(queryStr, safe="/:=&?#+!$,;'@()*[]")
          rawStr=encodedStr+MySK
          sn=(hashlib.md5(urllib.parse.quote_plus(rawStr).encode("utf8")).hexdigest())
      
          #生成url       
          
      url=urllib.parse.quote("http://api.map.baidu.com"+queryStr+"&sn="+sn,safe="/:=&?#+!$,;'@()*[]")
          print('Retrieving',url)

      2、输入url,利用urllib从API读取数据

          #从API读取数据
          uh=urllib.request.urlopen(url)
          data=uh.read().decode()
          print('Retrieved',len(data),'characters')

      3、利用json对返回数据进行解析。

      #解析数据
          try:
              js=json.loads(data)
          except:
              js=None
      
          if not js or 'status'not in js or js['status']!=0:
              print('======Failure====')
              print(data)
              continue
          print(json.dumps(js,indent=4,ensure_ascii=False))

      上一段可输出得到json格式的数据。下面即为输入“百度大厦”后程序输出的json格式数据。在这里一开始中文字符"商务大厦"不能正确显示,我从文章python中文编码&json中文输出问题中找到了答案,json.dumps函数默认转换为ASCII编码,中文字符就无法转换显示,因此要设置ensure_ascii=False。

      {
          "status": 0,
          "result": {
              "location": {
                  "lng": 116.30695597357376,
                  "lat": 40.05738753357608
              },
              "precise": 1,
              "confidence": 80,
              "comprehension": 100,
              "level": "商务大厦"
          }
      }

      最后,提取经纬度坐标等信息。

         #获取经纬度坐标和地址类型
          lat=js["result"]["location"]["lat"]
          lng=js["result"]["location"]["lng"]
          print('纬度',lat,'经度',lng)
          level=js["result"]["level"]
          print('地址类型',level)

      总结:按照规范发送url以及对返回json或xml格式数据正确解析,另外注意中文字符的编码问题,就可以上手API。怎么样?你也快来试试吧!

    # -*-: conding: utf-8 -*-
    import time
    import threading
    import json
    from urllib.request import urlopen
    from urllib.parse import quote,quote_plus
    import hashlib
    
    class BaiduMap(object):
    
        def __init__(self):
            pass
    
        @staticmethod
        def get_reverse_geo(lat, lng):
            '''
            根据经纬度获取逆编码地理信息
            api地址:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
            :param lat:
            :param lng:
            :return:
            '''
            # http://api.map.baidu.com/geocoder/v2/?callback=renderReverse&location=39.934,116.329&output=json&pois=1&ak=您的ak //GET请求
            queryStr = '/geocoder/v2/?callback=renderReverse&location=%s,%s&output=json&extensions_town=true&extensions_road=true&pois=0&ak=A4m18sdFRaGWMA8OxxHG7eqNXG3zqh' % (lat, lng) # Dp
    
            encodedStr = quote(queryStr, safe="/:=&?#+!$,;'@()*[]")  # 对queryStr进行转码,safe内的保留字符不转换
    
            rawStr = encodedStr + '72Xdzbki2WRFKdGRVcP1SOVTOzv7Us'  # 在最后直接追加上yoursk He
    
            # md5计算出的sn值7de5a22212ffaa9e326444c75a58f9a0
            # 最终合法请求url是http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=yourak&sn=7de5a22212ffaa9e326444c75a58f9a0
            sn = hashlib.md5(quote_plus(rawStr).encode('utf-8')).hexdigest()
            url = "http://api.map.baidu.com" + encodedStr + "&sn=" + sn
            print(url)
            abc = urlopen(url)
            data = str(abc.read().decode())[29:-1]
            try:
                result = json.loads(data)
            except Exception as e:
                print('异常经纬度',lat,lng)
                return {'result': None}
            return result
    
        @staticmethod
        def get_geocoder(addr):
            '''
            api地址:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
            :param addr:
            :return:
            '''
            # 以get请求为例http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=yourak
            while True:
                addr = addr.replace("#", "号")
                queryStr = '/geocoder/v2/?address=' + addr + '&output=json&ak=A4m18sdFRaGWMA8OxxHG7eqNXG3zqh' # Dp
    
                encodedStr = quote(queryStr, safe="/:=&?#+!$,;'@()*[]") # 对queryStr进行转码,safe内的保留字符不转换
    
                rawStr = encodedStr + '72Xdzbki2WRFKdGRVcP1SOVTOzv7Us' # 在最后直接追加上yoursk He
                # 最终合法请求url是http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=yourak&sn=7de5a22212ffaa9e326444c75a58f9a0
                sn = hashlib.md5(quote_plus(rawStr).encode('utf-8')).hexdigest()
                url = "http://api.map.baidu.com" + encodedStr + "&sn=" + sn
                print(url)  # 最终合法请求url
                abc = urlopen(url)
    
                response = str(abc.read(),encoding='utf8')
                try:
                    rabc = json.loads(response)
                except Exception as e:
                    # traceback.print_exc()
                    print('异常abc 为 html数据',addr)
                    return {}
                if 'status' in rabc and rabc['status'] == 1:
                    print(threading.current_thread(),rabc['msg'])
                    return {}
                elif 'status' in rabc and rabc['status'] == 302 :
                    print(threading.current_thread(),rabc['message'])
                    time.sleep(1000)
                elif 'result' in rabc:
                    return rabc['result']
                else:
                    return {}
    
    
    if __name__ == '__main__':
        place = '邯郸市馆陶县'
        length = len(place)
        utf8_length = len(place.encode('utf-8'))
        length = (utf8_length - length)/2 + length
        final = BaiduMap.get_geocoder(place)
        print(final)
        loc = final['location']
        print('get_reverse_geo',BaiduMap.get_reverse_geo(loc['lat'],loc['lng']))
    关注公众号 海量干货等你
  • 相关阅读:
    [BZOJ3535][Usaco2014 Open]Fair Photography
    [LOJ#2270][BZOJ4912][SDOI2017]天才黑客
    [UOJ#122][NOI2013]树的计数
    [BZOJ4816][Sdoi2017]数字表格
    [BZOJ2154]Crash的数字表格
    [BZOJ3529][Sdoi2014]数表
    [BZOJ2820]YY的GCD
    [BZOJ2301][HAOI2011]Problem b
    [UOJ#223][BZOJ4654][Noi2016]国王饮水记
    [BZOJ4653][Noi2016]区间
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734244.html
Copyright © 2011-2022 走看看