怎么样用Python实现地理编码
发布时间:2025-05-14 11:04:30 发布人:远客网络
一、怎么样用Python实现地理编码
今天看到一篇阿里云的文章天下武功,唯快不破,以物流行业为例,分析了 PostgreSQL与 Greenplum在地理位置信息处理,最佳路径算法,机器学习等方面的物流行业应用方法。其中提到了地址转换成坐标的问题,更专业些的名词应该是“地理编码”,即知道一个地址,如北京市海淀区上地十街10号,怎么样可以获取到对应的经纬度位置信息(40,116),或者反过来。
很多地图相关的厂商都提供了相关的API,我们可以直接利用这些API得到这些信息。比如百度的Geocoding API。
Geocoding API是一类接口,用于提供从地址到经纬度坐标或者从经纬度坐标到地址的转换服务,用户可以使用C#、C++、Java等开发语言发送请求且接收JSON、XML的返回数据。Geocoding API包括地址解析和逆地址解析功能:
地理编码:即地址解析,由详细到街道的结构化地址得到百度经纬度信息,例如:“北京市海淀区中关村南大街27号”地址解析的结果是“lng:116.31985,lat:39.959836”。同时,地理编码也支持名胜古迹、标志性建筑名称直接解析返回百度经纬度,例如:“百度大厦”地址解析的结果是“lng:116.30815,lat:40.056885”。
逆地理编码:即逆地址解析,由百度经纬度信息得到结构化地址信息,例如:“lat:31.325152,lng:120.558957”逆地址解析的结果是“江苏省苏州市虎丘区塔园路318号”。
不过,需要说明的一点是,若想使用百度的这套API的前提是,有百度账号并申请相应的Key。其实,除了百度之外,谷歌、ESRI、微软的Bing等都有类似的地理编码服务。不过这些服务大多没有专门针对Python的库并且彼此之间的Json结构也不一致。于是乎专治不服的Python大神做了一个专门的地理编码工具geocoder,将这些不同厂商的服务整合统一起来。
首先看一下它都支持哪些公司的地理编码服务:
Geocoder.ca CA& US Rate Limit
Google World Rate Limit, Policy
g= geocoder.google("1403 Washington Ave, New Orleans, LA 70130")
g= geocoder.arcgis(u"北京市海淀区上地十街10号")
[29.9287839,-90.08421849999999]
{'bbox': [-90.0855674802915,
'geometry':{'coordinates': [-90.08421849999999, 29.9287839],
'type':'Point'},
'properties':{'accuracy': u'ROOFTOP',
'address': u'1403 Washington Ave, New Orleans, LA 70130, USA',
'bbox': [-90.0855674802915,
'city': u'New Orleans',
'country': u'US',
'county': u'Orleans Parish',
'encoding':'utf-8',
'housenumber': u'1403',
'lng':-90.08421849999999,
'location':'1403 Washington Ave, New Orleans, LA 70130',
'neighborhood': u'Garden District',
'place': u'ChIJGyFHWc2lIIYRYSoneaXAUiw',
'postal': u'70130',
'provider':'google',
'quality': u'street_address',
'state': u'LA',
'status':'OK',
'street': u'Washington Ave'},
'type':'Feature'}
直接用Google尝试查询中文地址时失败
g= geocoder.google(u"北京市海淀区上地十街10号")
用百度应该没问题,不过我没有申请相应的key。切换到arcgis,能够成功编码
g= geocoder.arcgis(u"北京市海淀区上地十街10号")
g= geocoder.google([29.9287839,-90.08421849999999], method='reverse')
1403 Washington Ave, New Orleans, LA 70115, USA
g= geocoder.google([40.050934, 116.30079], method='reverse')
Bai Du Da Sha, Haidian Qu, Beijing Shi, China, 100193
g= geocoder.arcgis([40.050934, 116.30079], method='reverse')
Google转换成的是英文,但地址比较全。arcgis虽然是中文,但是详细的地址居然输出为了None,这有个X用。
geocoder的功能不止于此,它还可以查IP(包括自己的)。
g= geocoder.ip('199.7.157.0')
{'northeast': [38.976997, 121.976998],'southwest': [33.022997, 116.022998]}
空间信息既可以利用行政区划、自然地理区域等文本信息描述,也可以用坐标系统、数字(邮编等)来标识。利用地理编码技术,可以将空间信息的地理定位要素与相应的文本信息关联起来。本文主要介绍了geocoder地理编码这一小工具,可以方便快捷的利用地图等相关厂商提供的地理编码服务,将文字描述的位置转换成地图上的经纬度,或者通过地图上的某个位置坐标获得相应的位置信息文字描述。
二、PythonTkinter组件之Canvas
前言
大家小时候都玩过涂鸦吧,不管在哪里,只有有画纸和彩笔,画布上就能出现想象力丰富的图案。
大家小时候都玩过涂鸦吧,不管在哪里,只有有画纸和彩笔,画布上就能出现想象力丰富的图案。
上学时,我们面对难题,大家都喜欢在画纸上把自己的思路画出来
如今,工作中不管是个人还是团队,在画图软件画思维导图、项目框等等,图形化更加直观
画图工具在我们日常生活中随处可见,我们最常见的有Windows系统-画图,MAC系统的备忘录,那么我们来看一下,画图工具的构造吧
标题、每一栏描述语及形状等都是Label标签组件
空白面积最大的是Canvas画布组件
查看->显示状态是CheckbuttonF复选框组件
最后我们要退出或者小化放大窗口按钮是Button组件
我们可以看到,在画图工具中主要的作用就是在那空白的位置添加图片、画图等
本期,我们开始学习PythonTkinter标准组件Canvas画布相关属性和方法,Let'sgo~
Canvas(画布)是PythonTkinter标准组件,可放置图形、图相、组件等功能
Canvas画布是一个矩形区域用来绘制
Canvas画布可以添加线性、圆形、图片
Canvas画布支持添加的组件位置、外观
Canvas画布也提供Button、Label其他组件
Canvas画布提供操作图形标签方法
Canvas组件提供create_polygon创建多边形图形
坐标(x1,y1,x2,y2,x3,y3)可以使用random.randint()来生成
Canvas组件提供create_line()来绘制直线
坐标(x1,y1,x2,y2)可以使用random.randint()来生成
Canvas组件提供create_oval()来绘制椭圆形
坐标(x1,y1,x2,y2)可以使用random.randint()来生成
Canvas组件提供create_rectangle()来绘制矩形
坐标(x1,y1,x2,y2)可以使用random.randint()来生成
可以使用属性来设置矩形的外观,比如dash属性矩形线条是虚线
Canvas组件提供create_image()来添加图片
坐标(x1,y1)可以使用random.randint()来生成
要设置全局边Photo否则图片无法显示
Canvas组件可以支持绑定鼠标事件,使用鼠标进行绘制任意图形
以上图形绘制的颜色是随机产生的
颜色代码是以“#”开头的6位16进制代码
使用for循环进行random.randint()来随机产生每一位的代码
本期,我们学习PythonTkinter提供一个非常强大好玩的Canvas组件。我们使用Canvas组件可以精美的图形,增加我们程序的趣味性。
以上是本期内容,欢迎大佬们点赞评论指正,下次见~?(????`)比心??
三、python抓取网页时是如何处理验证码的
python抓取网页时是如何处理验证码的?下面给大家介绍几种方法:
这种验证码主要是通过用户输入图片中的字母、数字、汉字等进行验证。如下图:
解决思路:这种是最简单的一种,只要识别出里面的内容,然后填入到输入框中即可。这种识别技术叫OCR,这里我们推荐使用Python的第三方库,tesserocr。对于没有什么背影影响的验证码如图2,直接通过这个库来识别就可以。但是对于有嘈杂的背景的验证码这种,直接识别识别率会很低,遇到这种我们就得需要先处理一下图片,先对图片进行灰度化,然后再进行二值化,再去识别,这样识别率会大大提高。
这种是将备选碎片直线滑动到正确的位置,如下图:
解决思路:对于这种验证码就比较复杂一点,但也是有相应的办法。我们直接想到的就是模拟人去拖动验证码的行为,点击按钮,然后看到了缺口的位置,最后把拼图拖到缺口位置处完成验证。
第一步:点击按钮。然后我们发现,在你没有点击按钮的时候那个缺口和拼图是没有出现的,点击后才出现,这为我们找到缺口的位置提供了灵感。
我们知道拼图应该拖到缺口处,但是这个距离如果用数值来表示?
通过我们第一步观察到的现象,我们可以找到缺口的位置。这里我们可以比较两张图的像素,设置一个基准值,如果某个位置的差值超过了基准值,那我们就找到了这两张图片不一样的位置,当然我们是从那块拼图的右侧开始并且从左到右,找到第一个不一样的位置时就结束,这是的位置应该是缺口的left,所以我们使用selenium拖到这个位置即可。
这里还有个疑问就是如何能自动的保存这两张图?
这里我们可以先找到这个标签,然后获取它的location和size,然后 top,bottom,left,right= location['y'],location['y']+size['height']+ location['x']+ size['width'],然后截图,最后抠图填入这四个位置就行。
具体的使用可以查看selenium文档,点击按钮前抠张图,点击后再抠张图。最后拖动的时候要需要模拟人的行为,先加速然后减速。因为这种验证码有行为特征检测,人是不可能做到一直匀速的,否则它就判定为是机器在拖动,这样就无法通过验证了。
图文验证:通过文字提醒用户点击图中相同字的位置进行验证。
图标选择:给出一组图片,按要求点击其中一张或者多张。借用万物识别的难度阻挡机器。
这两种原理相似,只不过是一个是给出文字,点击图片中的文字,一个是给出图片,点出内容相同的图片。
这两种没有特别好的方法,只能借助第三方识别接口来识别出相同的内容,推荐一个超级鹰,把验证码发过去,会返回相应的点击坐标。
然后再使用selenium模拟点击即可。具体怎么获取图片和上面方法一样。
这种就很棘手,每一次出现的都不一样,但是也会出现一样的。而且拖动顺序都不一样。
但是我们发现不一样的验证码个数是有限的,这里采用模版匹配的方法。我觉得就好像暴力枚举,把所有出现的验证码保存下来,然后挑出不一样的验证码,按照拖动顺序命名,我们从左到右上下到下,设为1,2,3,4。上图的滑动顺序为4,3,2,1,所以我们命名4_3_2_1.png,这里得手动搞。当验证码出现的时候,用我们保存的图片一一枚举,与出现这种比较像素,方法见上面。如果匹配上了,拖动顺序就为4,3,2,1。然后使用selenium模拟即可。