分享一个自己写的 python 模块 guang_toolkit,欢迎使用

简要说明

Guang-Toolkit 工具包是我平时在 python 项目开发中抽象出的一些功能集合,可以实现以下功能:

  • 获取天气:包括历史天气、实时天气、未来天气
  • 地理/逆地理编码:坐标与地址的转换(高德坐标系)
  • 地理哈希:将坐标进行哈希编码
  • 发邮件:自动发邮件,支持发送附件
  • 操作 mysq 数据库:支持批量执行 sql 语句,将 select 结果转成dataframe,批量插入数据
  • 操作 redis 数据库:优化了 redis 的 set、get 和 delete 方法
  • pickle序列化:优化了特大数据的存储
  • 操作亚马逊s3:批量拉取数据,或者上传数据到S3
  • 地理可视化:中国的各行政区划的地区可视化

环境要求

python版本:3.x

安装

pip install guang_toolkit

guang_toolkit 依赖了其他三方模块,会比较大,下载加速的方法可以参考我之前写的文章《pip install 加速(修改为国内源)

教程

安装完之后,导入模块

import guang_toolkit as gt

1. 获取天气

首先初始化爬虫实例

weather = gt.WeatherCrawler()  # 初始化爬虫实例

实时天气

>>> weather.get_real_time_weather('上海市')
{
    "24h降水": "0", 
    "aqi_pm25": "114", 
    "城市": "上海", 
    "城市编码": "101020100", 
    "天气": "晴", 
    "日期": "11月19日(星期二)", 
    "更新时间": "10:07", 
    "温度(华氏)": "50", 
    "温度(摄氏)": "10", 
    "湿度": "44%", 
    "风向": "东风", 
    "风速": "<12km/h"
}

未来一小段时间的天气预报(逐小时)

>>> weather.get_hours_weather('上海市')
{
    "城市": "上海市", 
    "城市编码": "101020100", 
    "数据": [
        {
            "天气": "晴", 
            "日期": "2019111908", 
            "温度": "8", 
            "风向": "北风", 
            "风速": "3~4级"
        }, 
        ......
        {
            "天气": "晴", 
            "日期": "2019112007", 
            "温度": "10", 
            "风向": "北风", 
            "风速": "<3级"
        }
    ], 
    "更新时间": "07:30"
}

近7天天气预报(实际返回8天的结果,包括昨天)

>>> weather.get_7d_weather('上海市')
{
    "城市": "上海市", 
    "城市编码": "101020100", 
    "数据": [
        {
            "天气": "小雨转多云", 
            "日期": "18日", 
            "日期标识": "昨天", 
            "最低温度": "6", 
            "最高温度": "12", 
            "风向": "西北风",
            "风速": "<3级"
        }, 
        ......
        {
            "天气": "阴转多云", 
            "日期": "25日", 
            "日期标识": "周一", 
            "最低温度": "12", 
            "最高温度": "15", 
            "风向": "东北风",
            "风速": "3-4级"
        }
    ], 
    "更新时间": "07:30"
}

近15天天气预报(实际返回16天的结果,包括昨天)

>>> weather.get_15d_weather('上海市')
{
    "城市": "上海市", 
    "城市编码": "101020100", 
    "数据": [
        {
            "天气": "小雨转多云", 
            "日期": "18日", 
            "日期标识": "昨天", 
            "最低温度": "6", 
            "最高温度": "12", 
            "风向": "西北风",
            "风速": "<3级"
        }, 
        ......
        {
            "天气": "多云", 
            "日期": "3日", 
            "日期标识": "周二", 
            "最低温度": "7", 
            "最高温度": "11", 
            "风向": "北风",
            "风速": "3-4级转<3级"
        }
    ], 
    "更新时间": "07:30"
}

历史某日的天气

>>> weather.get_history_weather('上海市', '20190101')
{
    "url": "http://www.tianqihoubao.com/lishi/shanghai/20190101.html", 
    "城市": "上海市", 
    "天气": "阴/多云", 
    "日期": "20190101", 
    "温度": "6℃/2℃", 
    "风向风力": "北风 1-2级/北风 1-2级"
}

2. 地理/逆地理编码

本模块基于高德地图的地理/逆地理编码 API 实现,内置了个人的key,当然也支持大家用自己的 key。

首先初始化地图实例

crawler = gt.AMAPCrawler() # 初始化地图实例

解析单个坐标(逆地理编码)

>>> crawler.regeocode(121, 31)
{
    "adcode": "310118", 
    "address": "上海市青浦区练塘镇岳荡", 
    "city": "上海市", 
    "district": "青浦区", 
    "lat": 31, 
    "lng": 121, 
    "location": [
        121, 
        31
    ], 
    "province": "上海市"
}

解析单个地址(地理编码)

>>> crawler.geocode('上海市嘉定区汽车创新港')
{
    "address": "上海市嘉定区汽车创新港", 
    "city": "上海市", 
    "count": 1, 
    "district": "嘉定区", 
    "lat": 31.27914, 
    "lng": 121.195122, 
    "location": [
        121.195122, 
        31.27914
    ], 
    "province": "上海市"
}

批量解析坐标

>>> crawler.batch_process_regeocode([(121, 31), (116, 39)])
{
    "adcodes": [
        "310118", 
        "130632"
    ], 
    "addresses": [
        "上海市青浦区练塘镇岳荡", 
        "河北省保定市安新县大王镇334省道"
    ], 
    "cities": [
        "上海市", 
        "保定市"
    ], 
    "districts": [
        "青浦区", 
        "安新县"
    ], 
    "provinces": [
        "上海市", 
        "河北省"
    ]
}

批量解析地址

>>> crawler.batch_process_geocode(['上海市嘉定区汽车创新港', '北京市故宫博物院'])
{
    "adcodes": [
        "310114", 
        "110101"
    ], 
    "cities": [
        "上海市", 
        "北京市"
    ], 
    "districts": [
        "嘉定区", 
        "东城区"
    ], 
    "locations": [
        "121.195122,31.279140", 
        "116.397026,39.918058"
    ], 
    "provinces": [
        "上海市", 
        "北京市"
    ]
}

3. 地理哈希

地理哈希(geo-hash),又称地理编码/地理散列/地理空间索引,简单的理解就是:按照给定的精度,把地球表面切割成了一个个网格。一个坐标总能映射到某个网格中,这个网格的编号就是哈希值。哈希精度越大,网格越小。

地理哈希的好处是,将二维的经纬度转换成一维的字符串,一方面是可以节省存储空间,另一方面是提升搜索的速度,因此主要用于一些 LBS 应用,例如搜索某个 坐标附近有哪些出租车。

以下显示了不同精度下,网格在经度/纬度方向的边长长度,以及误差值。

>>> help(gt.encode)
            precision |  longitude  |  latitude
               1      |  5009.4km   |  4992.6km
               2      |  1252.3km   |   624.1km
               3      |   156.5km   |     156km
               4      |    39.1km   |    19.5km
               5      |     4.9km   |     4.9km
               6      |     1.2km   |    609.4m
               7      |    152.9m   |    152.4m
               8      |     38.2m   |       19m
               9      |      4.8m   |      4.8m
               10     |      1.2m   |    59.5cm
               11     |    14.9cm   |    14.9cm
               12     |     3.7cm   |     1.9cm
                      |             |
            precision |  delta_lng  |  delta_lat
               1      |  360/2**3   |  180/2**2
               2      |  360/2**5   |  180/2**5
               3      |  360/2**8   |  180/2**7
               4      |  360/2**10  |  180/2**10
               5      |  360/2**13  |  180/2**12
               6      |  360/2**15  |  180/2**15
               7      |  360/2**18  |  180/2**17
               8      |  360/2**20  |  180/2**20
               9      |  360/2**23  |  180/2**22
               10     |  360/2**25  |  180/2**25
               11     |  360/2**28  |  180/2**27
               12     |  360/2**30  |  180/2**30

对坐标进行哈希编码,精确到7位,注意:纬度在前,经度在后

>>> gt.encode(31, 121, 7) # 纬度在前,经度在后
'wtw037m'

逆解析哈希值,返回(纬度,经度)

>>> gt.decode('wtw037m')
(30.999984741210938, 120.99998474121094)

逆解析哈希值,并返回网格的边长(纬度,经度,纬度跨度,经度跨度)

>>> gt.decode_exactly('wtw037m')
(30.999984741210938, 120.99998474121094, 0.0006866455078125, 0.0006866455078125)

查看哈希值的边界(最大、最小的经度、纬度)

>>> gt.bbox('wtw037m')
{
    "e": 121.00067138671875,  # 最大经度
    "n": 31.00067138671875,  # 最大纬度
    "s": 30.999298095703125,  # 最小纬度
    "w": 120.99929809570312  # 最小经度
}

查看周围相邻的8个哈希值

>>> gt.neighbors('wtw037m')
['wtw037k', 'wtw037q', 'wtw037s', 'wtw037t', 'wtw037w', 'wtw037h', 'wtw037j', 'wtw037n']

查找半径500米内、指定精度的所有哈希值

>>> gt.hash_neighbors_radius(31, 121, radius_m=500, precision=7)
'wtw037q,wtw037g,wtw0376,wtw037y,wtw0374,wtw03e8,wtw037z,wtw03kh,wtw037n,wtw037t,wtw036v,wtw037x,wtw036w,wtw036y,wtw03e2,wtw03kj,wtw036s,wtw037p,wtw037w,wtw037h,wtw037e,wtw036z,wtw037r,wtw037u,wtw037f,wtw037d,wtw037v,wtw036t,wtw03kn,wtw0377,wtw037m,wtw03eb,wtw036g,wtw036f,wtw037j,wtw036u,wtw0375,wtw03db,wtw037s,wtw03e0,wtw037k'

4. 发邮件

本模块用于自动化脚本里发送邮件。

首先初始化邮箱实例(host,port 根据邮件服务商的不同而不同,可自行百度或联系本公司的IT)

mail = gt.Mail(
    user_name=邮箱,
    password=密码,
    host=host,
    port=port,
) # 初始化邮箱实例

对于163邮箱,可以用以下实例

mail = gt.Mail163(你的邮箱,登录密码) # 初始化邮箱实例

对于其他类型的邮箱,我还没试过,如有需要,欢迎联系我一起丰富这个工具~

写邮件

mail.write_mail(
    receivers='邮箱地址',  # 若给多人发送则用list:[收件人1,收件人2,...]
    subject='主题',  # 邮件主题(标题)
    text='内容', # 邮件正文
    pathes_attachment=['附件的路径'] # 如没有附件可为None
)

发邮件

mail.send_mail()

5. 操作 MySQL 数据库

本模块用于操作 MySQL 数据库,操作更加简单。

首先初始化 MySQL 实例(通过账密),

mysql = gt.MySQL(
    user_name='xxxx', 
    password='xxxx', 
    host='xxx', 
    port=3306, 
    db_name='xxxx'  # 默认连接的数据库名
) # 初始化MySQL实例

或者通过配置文件初始化,

mysql = gt.MySQL(path_config='配置文件地址')

执行 SQL 语句并返回结果(若是多句 SQL,用分割)

mysql.execute_sql('show tables;')

执行 SQL 并将返回值转成 DataFrame

df = mysql.read_sql_to_df('show tables;')

将DataFrame存到mysql里

mysql.to_sql(df, table_name, **kwargs)  # 支持传递更多参数,见 pandas 的 dataframe.to_sql 函数

6. 操作 Redis 数据库

本模块用于操作 Redis 数据库,特点是:

  • 继承自 redis.StrictRedis ,保留了 redis 的所有方法
  • 利用连接池来分配、管理和释放数据库连接,提高操作性能
  • 优化了大数据的 set、get 和 delete 方法

首先本地已经起了一个Redis服务,然后初始化 Redis 实例

redis = gt.Redis(db=0)  # 初始化 Redis 实例

或者连接远程Redis,

redis = gt.Redis(
    host=host, 
    port=port, 
    db=0
)

保存一个值,key为 ‘s’

redis.set('s', 1)

查看key为 ‘s’ 的数据

redis.get('s')
>>> 1

删除key为 ‘s’ 的数据

redis.delete('s')

7. Pickle 序列化

本模块用于磁盘存储数据,特点是:

  • 基于 pickle 模块,默认用最高的协议(pickle.HIGHEST_PROTOCOL)
  • 取消了 pickle 对于单个文件大小的限制,优化特大数据的存储

保存数据

gt.pickle_dump(666, 'test.pkl')

读取数据

>>> gt.pickle_load('test.pkl')
666

8. 操作亚马逊(AWS)S3

从 S3 上拉数据,get 方法支持批量拉取数据和拉取特定数据

初始化 S3 实例,

s3 = gt.S3(
    access_key_id='xxx', 
    secret_access_key='xxx', 
    region='xxx', 
    bucket_name='xxx', 
    endpoint_url='xxx'
)  # 初始化 S3 实例

或者通过配置文件初始化

s3 = gt.S3(path_config=配置文件地址)

拉取某个文件(目前仅支持csv和parquet格式)

s3.get('aaa/bbb/ccc.csv')
s3.get('aaa/bbb/ccc.parquet')

拉取某个目录下的所有文件(目前仅支持 csv 和 parquet 格式)

s3.get('aaa/bbb/ccc', suffix='.csv')
s3.get('aaa/bbb/ccc', suffix='.parquet')

保存数据到 S3 上(目前仅支持 csv 和 parquet 格式)

s3.set(df, 'aaa/bbb/ccc.csv')
s3.set(df, 'aaa/bbb/ccc.parquet')

上传文件到 S3 上

s3.upload_file('local_path', 'remote_path')

下载文件到 S3 上

s3.download_file('remote_path', 'local_path')

9. 可视化

环状分布图

gt.donut([1, 1, 2, 1])

地理可视化

首先,初始化中国实例(用于获取最新的行政区划)

china = gt.China() # 初始化中国实例

地理可视化,全国、省、市、区都可以画~

china.plot(adcode_or_name='浙江', subdistrict=1, area_threshold=0.005)

这里解释下参数:

  • adcode_or_name:adcode或者名称,支持模糊名称(如内蒙古自治区、内蒙都一样)
  • subdistrict: 设置绘制下级行政区级数,可选值为0/1/2/3,默认值为0,当绘图对象的本身级别较低时(如县),subdistrict只能为0,以此类推。
    • 0:不绘制下级行政区,适用于全国/省/市/区;
    • 1:绘制下一级行政区,适用于全国/省/市;
    • 2:绘制下两级行政区,适用于全国/省;
    • 3:绘制下三级行政区,适用于全国;
  • area_threshold: 绘图阈值,面积小于该值的多边形将不再绘制在地图上,该参数用于加速绘图

如果对提供的默认绘图方法不满意,也可以用下面的方法获取到所有边界坐标,然后再自行绘图~

import matplotlib.pyplot as plt

# 获取所有边界坐标
polylines = china.get_all_polylines('上海', subdistrict=2)

# 绘图
if polylines:
    plt.figure(figsize=(12, 12))
    for polyline in polylines:
        plt.plot(polyline[:, 0], polyline[:, 1])
    plt.axis("equal")
    plt.show()
else:
    print('找不到边界坐标,请确认 adcode 或名称是否正确,或者 subdistrict 值设置过大')

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值