日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python地址转经纬度_经纬度地址转换的方法集合(Python描述)

發布時間:2024/1/1 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python地址转经纬度_经纬度地址转换的方法集合(Python描述) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python 2.7

IDE Pycharm 5.0.3

Geopy 1.11

前言

這只是我想做的一部分,寫一塊太大了,單獨記錄

目的

獲取2015年GDP TOP100城市并獲取城市對應經緯度,存入txt后續操作

獲取GDP TOP100城市

查詢網址如下http://www.redsh.com/a/20160126/171501.shtml

2015中國100大城市GDP排行榜TOP100出爐!

頁面的效果大概是這樣的~慘不忍睹的格式,花了我好多時間提取。。。。

元素大概是這樣的

ok,先把TOP100城市爬下來再說

方法1:靜態爬取

采用urllib2+BS4+re(更多靜態爬取方法點擊這里),當然你也可以采用request來代替urllib2,這里我只做個試驗,所以用了urllib2,廢話不多說,直接上代碼!

# 采用urllib2+BS4進行靜態網頁解析

def getCityByBS4(url):

html = urllib2.urlopen(urllib2.Request(url)).read().decode('gbk')

soup = BeautifulSoup(html,'lxml')

x = soup.find_all('p')

t=1

cityLocationList = []

cityLocationListOnlyLatLng =[]

for i in x:

if t > 5 and t<106:

city1 = i.get_text()

city1 = city1.encode('utf-8')

# 數據清洗過程

city1 = re.split('\.',city1)[1]

city1 = re.split('(',city1)[0]

if len(city1)>13:

city2 = city1[0:6]

else:

city2 =city1.strip()

try:

lat_lng = getLocation_xml(city2+"市")

city_location = "%s %s"%(city2,str(lat_lng))

city_locationOnlyLatLng = lat_lng

cityLocationList.append(city_location)

cityLocationListOnlyLatLng.append(city_locationOnlyLatLng)

#write2txt(city_location,"City&LocationBS4.txt")

print city_location

except:

print "something wrong about city:",city2

t +=1

return cityLocationList,cityLocationListOnlyLatLng

# 返回了一個有城市和經緯度對應的列表如:上海 31.249162,121.487899

# 還返回了一個只有經緯度的列表如 :31.249162,121.487899

#寫入txt操作子函數

def write2txt(file,txtname):

f = open(txtname,'a')

f.write(file)

f.write("\n")

f.close()

# please use this with try except/finall f.close()

# 程序入口

if __name__ == '__main__':

url = 'http://www.redsh.com/a/20160126/171501.shtml'

city_locationList,cityLocationListOnlyLatLng= getCityByBS4(url)

print city_locationList

for i in city_locationList:

write2txt(i,"city&locaionByBS4.txt")

for j in cityLocationListOnlyLatLng:

write2txt(j,"LocaionOnlyByBS4.txt")

最后效果如圖所示,至于以后要用哪個直接選擇就行了

有地址對應和只有經緯度的

方法2:動態爬取

采用Selenium+PhantomJS的方法(更多Selenium使用案例點擊這里)

(這里是有趣的專題),這回沒用Firefox瀏覽器了,也就是演示作用而已,無頭PhantomJS就行了,也是直接上代碼

#采用selenium+phantomjs進行動態解析

def getCityBySelenium(url):

driver = webdriver.PhantomJS(executable_path="phantomjs.exe")

driver.get(url)

cityLocationList = []

cityLocationListOnlyLatLng =[]

for i in range(6,106):

elem_city = driver.find_element_by_xpath("//font[@id='zoom']/p[%d]"%i).text

elem_city = elem_city.encode('utf-8')

try:

city = re.split("[\.]",elem_city)[1]

city = re.split("(",city)

city1 = city[0]

# 一個中文字符占3個長度!!

if len(city1)>13:

city2 = city1[0:6]

else:

city2 =city1.strip()

lat_lng = getLocation_xml(city2+"市")

city_location = "%s %s"%(city2,str(lat_lng))

city_locationOnlyLatLng = lat_lng

#write2txt(city_location,"City&LocationBySelenium.txt")

print city_location

cityLocationList.append(city_location)

cityLocationListOnlyLatLng.append(city_locationOnlyLatLng)

except:

print 'something wrong with ',elem_city

# 調用完后記得關閉!!!!!不然phantomjs一直占用內存

driver.close()

driver.quit()

return cityLocationList,cityLocationListOnlyLatLng

# 返回了一個有城市和經緯度對應的列表如:上海 31.249162,121.487899

# 還返回了一個只有經緯度的列表如 :31.249162,121.487899

#至于主程序,只要把city_locationList,cityLocationListOnlyLatLng= getCityByBS4(url)中的getCityByBS4(url)換成getCityBySelenium(url),之后改一下txt文件名就行了,當然,這些函數都是在一個py文件里的

效果就不展示了,和上面靜態處理一樣

靜態處理 VS 動態處理

靜態處理urllib/request

優點:速度快

缺點:處理動態網頁抓取不全

動態處理Selenium+PhantomJS/Firefox

優點:能夠處理任何靜態、動態網頁

缺點:速度慢

總結:如果能判斷出來是靜態頁面的,使用urllib和request比較方便和快捷一點,但是設計交互元素比較多的動態網頁,靜態方法是沒有辦法處理好的,直接上Selenium把!

正題時間

獲取城市之后,怎么轉化為對應的經緯度呢,這里也有兩個方法

方法1:調用API接口

簡單一句話介紹API接口,你不需要知道里面是怎么操作的,只需要知道你輸入什么,經過一些亂七八糟的處理后(不用你管),返回給你一個友好的值就可以了。

舉個例子,我輸入城市名字,調用接口后,它返回給我經緯度,ok,就是這么簡單。

這次使用的是百度地圖的API,詳見官網百度地圖API

就像訪問網頁抓取元素一樣,然后她會返回json/xml格式的數據,只是,這回的url變成了如下

#獲取json格式的url

http://api.map.baidu.com/geocoder?address=城市&output=json&key=f247cdb592eb43ebac6ccd27f796e2d2

#返回xml格式的url

http://api.map.baidu.com/geocoder?address=城市&output=xml&key=f247cdb592eb43ebac6ccd27f796e2d2

以json返回的舉個例子,xml一樣道理

#調用API返回json格式

import urllib2

url= 'http://api.map.baidu.com/geocoder?address=北京&output=json&key=f247cdb592eb43ebac6ccd27f796e2d2'

html = urllib2.urlopen(urllib2.Request(url))

json1 = html.read() #轉化為str類型

print json1

返回的形式如下,只需要在爬取其中的lng和lat就行了,至于怎么取出其中的值,可以轉化為json字典用字典的方法取值

"status":"OK",

"result":{

"location":{

"lng":116.395645,

"lat":39.929986

},

"precise":0,

"confidence":10,

"level":"\u57ce\u5e02"

}

}

完整的json格式調用子函數

def getLocation_json(addr):

url= 'http://api.map.baidu.com/geocoder?address=%s&output=json&key=f247cdb592eb43ebac6ccd27f796e2d2'%(addr)

html = urllib2.urlopen(urllib2.Request(url))

json1 = html.read() #轉化為str類型

hjson =json.loads(json1) #轉化為dict類型

lng = hjson['result']['location']['lng'] # 經度

lat = hjson['result']['location']['lat'] # 緯度

lng_lat = [lng, lat]

return lng_lat

#返回json數據格式

{

"status":"OK",

"result":{

"location":{

"lng":116.395645,

"lat":39.929986

},

"precise":0,

"confidence":10,

"level":"\u57ce\u5e02"

}

}

而采用xml返回形式的如下所示,自己選擇喜歡的返回形式利于你的下一步處理就可以了。

#返回xml數據格式

OK

39.929986

116.395645

0

10

城市

返回xml格式的完整子程序

def getLocation_xml(addr):

url= 'http://api.map.baidu.com/geocoder?address=%s&output=xml&key=f247cdb592eb43ebac6ccd27f796e2d2'%(addr)

html = urllib2.urlopen(urllib2.Request(url))

xml = html.read()

bs_getDetail = BeautifulSoup(xml,'lxml')

#方法一,直接根據路徑找

lng =float(bs_getDetail.result.location.lng.string)

lat = float(bs_getDetail.result.location.lat.string)

'''

#方法二,使用find方法+正則表達式

lat = bs_getDetail.find('lat')

lng = bs_getDetail.find('lng')

pattern = '\d+\.\d+'

lat = re.findall(pattern,str(lat))[0]

lng = re.findall(pattern,str(lng))[0]

'''

lat_lng = "%s,%s"%(lat,lng)

return lat_lng

方法2:使用Geopy包

貼心的開發者已經把它放在github上了,(點擊這里進行下載)直接下載安裝即可使用。很方便的!

官方用法實例

官方描述用法

實現的功能和上面調用API一樣,輸入城市輸出經緯度,而且,還有輸入經緯度反向輸出城市的方法,很好用!

以下是我自己用的兩個子函數

# 調用Geopy包進行處理-獲取城市名

def getCitynameByGeo(lat_lng):

#知道經緯度獲取地址

geolocator = Nominatim()

location = geolocator.reverse(lat_lng)

addr = location.address

print addr

cityname = re.split("[/,]",addr)[-5].strip()

print cityname

return addr,cityname

# 調用Geopy包進行處理-獲取經緯度

def getLocationByGeo(cityname):

#知道地址獲取經緯度

geolocator = Nominatim()

location2 = geolocator.geocode(cityname)

lat = location2.latitude

lng = location2.longitude

return "%s %s,%s"%(cityname,lat,lng)

直接要用的時候調用就可以了,大家可以自己試試,這個就不用在自己對json或者xml數據進行清洗和裁剪了。省時省力。

測試一下

就拿剛才用第一種方法寫進去的txt中數據進行測試

import re

#導入包,實例化對象

from geopy.geocoders import Nominatim

# 調用Geopy包進行處理-獲取城市名

def getCitynameByGeo(lat_lng):

#知道經緯度獲取地址

geolocator = Nominatim()

location = geolocator.reverse(lat_lng)

addr = location.address

print addr

cityname = re.split("[/,]",addr)[-5].strip()

return addr,cityname

f = open("LocaionOnlyByBS4.txt")

lines = f.readlines()

for line in lines:

getCitynameByGeo(line)

測試效果如下,還是很不錯的,就是要提取城市的時候有點麻煩,格式并不是統一的。

長治路, 虹口區, 虹口區 (Hongkou), 上海市, 200080, 中國

織染局胡同, 東城區, 北京市, 東城區, 北京市, 100010, 中國

春風路, 東山街道, 越秀區 (Yuexiu), 廣州市 / Guangzhou, 廣東省, 港方口岸區 Hong Kong Port Area, 510623, 中國

...

調用API VS Geopy

Geopy比較好吧,畢竟很加符合pythonic,包之間的相互使用,界限分明,而且對于不熟悉bs4,json,re的童鞋來說,這個簡直遇到了親人一樣親切!

當然,API的好處也很多,至少我是第一次調用地圖api,其中包含的內容太多了,可以返回的內容也不止經緯度那么簡單,如果以后要返回其他的值,估計還是得靠api

9.18補充

之后的測試發現,geopy的能力僅限于大城市,如果街道的話,是會報錯的,而調用API則照樣能搜索出來,以下是測試圖

調用百度地圖API

import urllib2

url= 'http://api.map.baidu.com/geocoder?address=哈爾濱市中央大街112號&output=json&key=f247cdb592eb43ebac6ccd27f796e2d2'

html = urllib2.urlopen(urllib2.Request(url))

json1 = html.read()

print json1

結果返回正常(當然精度不能保證,理由大家都懂的)

{

"status":"OK",

"result":{

"location":{

"lng":126.657717,

"lat":45.773225

},

"precise":0,

"confidence":10,

"level":"\u57ce\u5e02"

}

}

而采用geopy包實現操作

from geopy.geocoders import Nominatim

def getLocationByGeo(cityname):

#知道地址獲取經緯度

geolocator = Nominatim()

location2 = geolocator.geocode(cityname)

lat = location2.latitude

lng = location2.longitude

return "%s %s,%s"%(cityname,lat,lng)

x = getLocationByGeo("哈爾濱市中央大街112號")

print x

而返回報錯了

AttributeError: 'NoneType' object has no attribute 'latitude'

所以,街道或者比較小的地方還是百度地圖api比較靠譜

btw--大家都要聯網才能用的0.0

Q&A

1.分割字符串的時候,竟然出現了�亂碼問題,原來中文字符占三個長度,,,,好吧,用的挺長時間的len(),第一次遇到中文,額。

str1 = "中文"

print len(str1)

#6

#一個中文占了三個長度!!!!!,難怪出現長度分割�亂碼問題!!!

2.個別城市調用API時出錯,比如西安這個城市(使用geopy沒有這個問題)

lng_lat = getLocation_json("西安")

print lng_lat

#輸出以下

Traceback (most recent call last):

File "C:/Users/MrLevo/PycharmProjects/test/llll.py", line 208, in

lng_lat = getLocation_json("西安")

File "C:/Users/MrLevo/PycharmProjects/test/llll.py", line 203, in getLocation_json

lng = hjson['result']['location']['lng'] # 經度

TypeError: list indices must be integers, not str

于是乎,抖了個機靈,加了個"市",哈哈,解決!百度這API做的也不走心啊,這么大一個省會沒有,測試之后,不僅僅是西安躺槍,100個城市,就有七八個讀不出來,,,哎,我都加上了"市",才行。

lng_lat = getLocation_json("西安市")

print lng_lat

#[108.953098, 34.2778]

總結

以后先找包,再找api,包能實現的,沒必要那么復雜。

不過也訓練了一下api的調用,熟悉了一下json,xml,re等。果然時間久了不用還是會忘的很快哈~

最后祝大家中秋快樂!然而我還在實驗室加班。。。。苦并快樂著,哈哈

致謝

總結

以上是生活随笔為你收集整理的python地址转经纬度_经纬度地址转换的方法集合(Python描述)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。