zoukankan      html  css  js  c++  java
  • python中通过客户端IP拿到所在城市和当地天气信息—附带项目案例

    熟悉老一代QQ的小伙伴可能都知道,很早以前的QQ,鼠标滑到头像的位置,你的位置和IP会在详情页显示,那么这个是如何做到的呢?下面我们就来玩一玩这个东西

    首先,需求分析:

    1、拿到客户端IP

    2、通过IP拿到客户端所在地区

    3、通过地区拿到当地天气

    4、整合功能,展示给用户

    第一步,如何拿到用户IP

    我们以Django环境为例

    # 客户端的请求,IP信息会在请求头中
    
    request.META['REMOTE_ADDR'] 
    #
    request.META.get('HTTP_X_FORWARDED_FOR')
    
    里面

    为什么是或呢?

    这是因为有些服务器做了代理或者使用nginx等,在REMOTE_ADDR中会拿到本地回环地址:127.0.0.1

    这时候真实的客户端IP在HTTP_X_FORWARDER_FOR中。

    如果你是测试环境,项目跑在内网,又想拿到本地公网IP做测试,那怎么做呢?诶,这里也有办法

            import re,requests
    
            url = 'http://txt.go.sohu.com/ip/soip'
            response = requests.get(url)
            text = response.text
            ip = re.findall(r'd+.d+.d+.d+', text)[0]
            print("默认访客ip:%s"%ip)

    通过requests模块和re模块向这个网址发送请求和解析匹配,你就可以拿到你的公网IP

    第二步、找到对应城市

    好了,IP解决了,那么接下来就是通过IP解析所在城市

    python中有一个第三方库,专门来干这件事请,解析国家、城市、地区等等

    它就是 geoip2 模块,它依赖服务供应商的数据库文件,这里我用city数据库来实现

    数据库文件下载地址:http://dev.maxmind.com/geoip/geoip2/geolite2/

     据说这两种都可以解压出城市的数据库文件,我这里已城市的为例

    下载解压后

    这就是我们需要的数据库文件

     我们把它放到项目中的一个文件夹中,在settings中配置好它的路径,这样我们就可使用它了

    使用也是十分简单

        read = geoip2.database.Reader(settings.CITY_DB)  # mmdb文件路径,提前在settings文件中配置好
        c = read.city(ip)    # 放入需要检测的IP
        target_city = c.city.names.get("ja")

    这样我们就拿到IP对应的城市信息了 target_city

    有兴趣你可以打印下c、c.city、c.city.name 各自是什么东西

    在这里由于这是人家给你免费用的版本,比起商业付费版本,在精确度和覆盖面上会有差别,不过平常用用足够了

    第三步、爬取当地天气信息

    用于爬取天气信息的网站比较多,百度一下都可以找到

    现在我们以其中一个为例:

        path = 'http://wthrcdn.etouch.cn/weather_mini?city=上海' 
        response = requests.get(path)  # 对该地址和参数进行get请求
        result = response.json()     # 将返回的结果转成json串

    我们拿到的result是一个大字典,如下:

    a ={
        'data':
            {
                'yesterday':
                     {
                         'date': '10日星期三', 'high': '高温 28℃', 'fx': '东风', 'low': '低温 19℃', 'fl': '<![CDATA[<3级]]>', 'type': '雷阵雨'
                     },
                'city': '北京',
                'forecast':
                    [{'date': '11日星期四', 'high': '高温 30℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 21℃', 'fengxiang': '东南风', 'type': '多云'},
                     {'date': '12日星期五', 'high': '高温 32℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 22℃', 'fengxiang': '西南风', 'type': '多云'},
                     {'date': '13日星期六', 'high': '高温 33℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 23℃', 'fengxiang': '北风', 'type': '多云'},
                     {'date': '14日星期天', 'high': '高温 33℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 23℃', 'fengxiang': '北风', 'type': ''},
                     {'date': '15日星期一', 'high': '高温 35℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 24℃', 'fengxiang': '东南风', 'type': ''}
                     ],
                'ganmao': '各项气象条件适宜,发生感冒机率较低。但请避免长期处于空调房间中,以防感冒。', 'wendu': '29'
            },
        'status': 1000,
       'desc': 'OK' }

    这么一看是不是非常爽呢,这不就是字典呢,你想干嘛干嘛了

    第四步、渲染到项目中

    这里以我写的一个小项目为例

        
      # 第一步拿到客户端IP
      if request.META['REMOTE_ADDR'] != '127.0.0.1': # if拿到IP ip = request.META['REMOTE_ADDR'] print("REMOTE_ADDR 访客ip:%s" % ip) elif request.META.get('HTTP_X_FORWARDED_FOR'): ip = request.META['HTTP_X_FORWARDED_FOR'] print("HTTP_X_FORWARDED_FOR访客ip:%s" % ip) else: #如果没有符合的IP,默认本地 path = 'http://txt.go.sohu.com/ip/soip' response = requests.get(path) text = response.text ip = re.findall(r'd+.d+.d+.d+', text)[0] print("默认访客ip:%s"%ip) # 第二步、拿到IP对应城市
      read
    = geoip2.database.Reader(settings.CITY_DB) # mmdb文件路径 c = read.city(ip) target_city = c.city.names.get("ja") # 拿到城市,可能存在匹配不到 if not target_city: target_city = '上海'
      # 第三步、爬取当地天气
      path
    = 'http://wthrcdn.etouch.cn/weather_mini?city=%s' % target_city # url = path % location response = requests.get(path) # 对该地址和参数进行get请求 result = response.json() # 将返回的结果转成json串 if result.get("status") != 1000: wea = '' else: wea = result.get('data').get("forecast")[0].get("type") # ganmao = result.get("ganmao") print(target_city,wea)

    前端展示:

     好了,这篇就到这里了,更多好玩的功能,欢迎留言~

  • 相关阅读:
    入职小白随笔之Android四大组件——内容提供器详解(Content Provider)
    入职小白随笔之Android四大组件——广播详解(broadcast)
    入职小白随笔之Android四大组件——活动详解(activity)
    入职小白随笔之高通项目编译流程
    Java基础学习-Random类和Java数组
    Java基础学习-流程控制语句
    Java基础学习-三元运算符和键盘录入的基本步骤和使用
    Java基础学习-Eclipse综述和运算符的使用
    Java基础学习-类型转换之隐式转换
    SQLite----Android Studio3.6.3 当前最新版本数据库查找与导出方法
  • 原文地址:https://www.cnblogs.com/dongxixi/p/11176301.html
Copyright © 2011-2022 走看看