1. python讀取圖片exif屬性中的GPS信息
智能手機或平板如果在拍照時開啟定位服務,照片中就會記錄拍照位置信息和拍攝時間。如果將原始照片直接發送發布到網上,無意中就泄漏了自己的位置信息,有惡意企圖的人可能會通過照片分析出你的家庭住址和工作單位。 python有很多工具庫可以解析圖片的exif元數據信息,筆者喜歡使用exifread這個庫。
2. 完整代碼(需要使用python3)
圖片exif屬性中的經緯度是“度,分,秒”的形式,如:[25, 34, 5927/100],需要轉換成類似“16.439683,39.941649999”這樣的形式。 除經緯度外,還要讀取GPS元數據中的東西半球和南北半球標識。 經緯度轉換成地理位置需要調用地圖服務接口,本程序代碼采用百度的逆地理編碼服務API接口,調用接口需要申請服務密鑰。 筆者自己利用手機拍照測試,程序分析后得到的位置信息基本沒有誤差。
#!/bin/python
#coding:utf8
import os
import exifread
import re
import sys
import requests
import json__author__ = 'DaDaLuLa'#************************************************************************
#代碼功能: #
# 1.讀取所有圖片文件的exif信息 #
# 2.提取圖片中的經緯度,將度、分、秒轉換為小數形式 #
# 3.利用百度地圖API接口將經緯度轉換成地址形式 #
#************************************************************************#遍歷文件夾及子文件夾中的所有圖片,逐個文件讀取exif信息
def get_pic_GPS(pic_dir): items = os.listdir(pic_dir) for item in items: path = os.path.join(pic_dir, item) if os.path.isdir(path): get_pic_GPS(path) else: imageread(path)#將經緯度轉換為小數形式
def convert_to_decimal(*gps):#度if '/' in gps[0]:deg = gps[0].split('/')if deg[0] == '0' or deg[1] == '0':gps_d = 0else:gps_d = float(deg[0]) / float(deg[1])else:gps_d = float(gps[0])#分if '/' in gps[1]:minu = gps[1].split('/')if minu[0] == '0' or minu[1] == '0':gps_m = 0else:gps_m = (float(minu[0]) / float(minu[1])) / 60else:gps_m = float(gps[1]) / 60#秒if '/' in gps[2]:sec = gps[2].split('/')if sec[0] == '0' or sec[1] == '0':gps_s = 0else:gps_s = (float(sec[0]) / float(sec[1])) / 3600else:gps_s = float(gps[2]) / 3600decimal_gps = gps_d + gps_m + gps_s#如果是南半球或是西半球if gps[3] == 'W' or gps[3] == 'S' or gps[3] == "83" or gps[3] == "87":return str(decimal_gps * -1)else:return str(decimal_gps)#讀取圖片的經緯度和拍攝時間
def imageread(path):f = open(path,'rb')GPS = {}Data = ""try:tags = exifread.process_file(f)except:return '''for tag in tags: print(tag,":",tags[tag])'''#南北半球標識if 'GPS GPSLatitudeRef' in tags:GPS['GPSLatitudeRef'] = str(tags['GPS GPSLatitudeRef'])else:GPS['GPSLatitudeRef'] = 'N' #缺省設置為北半球#東西半球標識if 'GPS GPSLongitudeRef'in tags:GPS['GPSLongitudeRef'] = str(tags['GPS GPSLongitudeRef'])else:GPS['GPSLongitudeRef'] = 'E' #缺省設置為東半球#海拔高度標識if 'GPS GPSAltitudeRef' in tags:GPS['GPSAltitudeRef'] = str(tags['GPS GPSAltitudeRef'])#獲取緯度if 'GPS GPSLatitude' in tags:lat = str(tags['GPS GPSLatitude'])#處理無效值if lat == '[0, 0, 0]' or lat == '[0/0, 0/0, 0/0]':returndeg, minu, sec = [x.replace(' ', '') for x in lat[1:-1].split(',')]#將緯度轉換為小數形式GPS['GPSLatitude'] = convert_to_decimal(deg, minu, sec,GPS['GPSLatitudeRef'])#獲取經度if 'GPS GPSLongitude' in tags:lng = str(tags['GPS GPSLongitude'])#處理無效值if lng == '[0, 0, 0]' or lng == '[0/0, 0/0, 0/0]':returndeg, minu, sec = [x.replace(' ', '') for x in lng[1:-1].split(',')]#將經度轉換為小數形式GPS['GPSLongitude'] = convert_to_decimal(deg, minu, sec,GPS['GPSLongitudeRef'])#對特殊的經緯度格式進行處理#獲取海拔高度if 'GPS GPSAltitude' in tags:GPS['GPSAltitude'] = str(tags["GPS GPSAltitude"])#獲取圖片拍攝時間if 'Image DateTime' in tags:GPS["DateTime"] = str(tags["Image DateTime"])elif "EXIF DateTimeOriginal" in tags:GPS["DateTime"] = str(tags["EXIF DateTimeOriginal"])if 'GPSLatitude' in GPS:#將經緯度轉換為地址convert_gps_to_address(GPS)#利用百度全球逆地理編碼服務(Geocoder)Web API接口服務將經緯轉換為位置信息
def convert_gps_to_address(GPS):secret_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'#百度密鑰lat, lng = GPS['GPSLatitude'], GPS['GPSLongitude']#注意coordtype為wgs84ll(GPS經緯度),否則定位會出現偏差baidu_map_api = "http://api.map.baidu.com/geocoder/v2/?coordtype=wgs84ll&location={0},{1}&output=json&pois=0&ak={2}".format(lat,lng,secret_key)content = requests.get(baidu_map_api).textgps_address = json.loads(content)#結構化的地址formatted_address = gps_address["result"]["formatted_address"]#國家(若需訪問境外POI,需申請逆地理編碼境外POI服務權限)country = gps_address["result"]["addressComponent"]["country"]#省province = gps_address["result"]["addressComponent"]["province"]#城市city = gps_address["result"]["addressComponent"]["city"]#區district = gps_address["result"]["addressComponent"]["district"]#語義化地址描述sematic_description = gps_address["result"]["sematic_description"]#將轉換后的信息寫入文件 with open("gps_address.csv","a+") as csv:csv.write(GPS["DateTime"] + "|" + formatted_address + "|" + country + "|" + province + "|" + city + "|" + district + "|" + sematic_description + "\n") if __name__ == "__main__":get_pic_GPS("./photo/")
從網站下載多張照片,測試運行結果如下: 2017:07:27 22:02:52|天津市河東區長征路8號|中國|天津市|天津市|河東區|水利家園東79米 2018:10:28 17:53:32|廣東省廣州市天河區員村二橫路|中國|廣東省|廣州市|天河區|程界子富新村內 2017:08:30 05:52:54|山東省濟南市濟陽縣經四路|中國|山東省|濟南市|濟陽縣|嘉景苑南
3. 某色情網站照片GPS批量提取
筆者無意中發現,互聯網上傳播的一些色情圖片保留了完整的GPS等元數據信息。為了分析色情圖片的拍攝位置,從某網站爬取了34萬張少兒不宜的圖片。利用上文中的程序進行分析,共獲取了3000余張圖片包含的經緯度信息,利用百度地圖API接口轉換成對應的精確地理位置信息 。 photo.jpg
經程序分析后獲取的部分數據如下(多數位置信息能夠精確所在的小區和酒店,以下結果對具體地址加*號處理): 2017:10:16 15:13:43|四川省成都市雙流縣華陽大道4段-200|中國|四川省|成都市|雙流縣|成都栢頓*大酒店內 2017:10:16 15:43:39|四川省成都市雙流縣華陽大道4段-200|中國|四川省|成都市|雙流縣|泊爾*酒店 2017:10:24 19:41:37|四川省成都市雙流縣華陽大道4段-200|中國|四川省|成都市|雙流縣|泊爾*酒店 2017:08:31 22:04:58|山東省濰坊市諸城市|中國|山東省|濰坊市|諸城市|萬*家園內 2017:08:31 22:05:20|山東省濰坊市諸城市|中國|山東省|濰坊市|諸城市|萬*家園內 2017:08:31 22:04:29|山東省濰坊市諸城市|中國|山東省|濰坊市|諸城市|萬*家園內 2017:08:31 22:07:36|山東省濰坊市諸城市|中國|山東省|濰坊市|諸城市|萬*家園內 2018:01:24 23:21:23|河南省許昌市長葛市鐵東路|中國|河南省|許昌市|長葛市|幸*小區 2018:01:24 23:21:20|河南省許昌市長葛市鐵東路|中國|河南省|許昌市|長葛市|幸*小區 018:08:31 22:56:52|廣東省深圳市寶安區航城大道|中國|廣東省|深圳市|寶安區|南航明*花園內 2018:11:14 21:43:42|廣東省深圳市寶安區航城大道|中國|廣東省|深圳市|寶安區|南航明*花園內 2018:06:21 21:43:45|遼寧省沈陽市于洪區中央大街|中國|遼寧省|沈陽市|于洪區|沈陽世紀高爾*俱樂部內 2018:08:23 19:04:38|遼寧省沈陽市大東區滂江街|中國|遼寧省|沈陽市|大東區|龍之*暢園內 2018:10:24 23:16:13|遼寧省沈陽市于洪區十一號街|中國|遼寧省|沈陽市|于洪區|水墨*青內 2018:10:24 23:12:40|遼寧省沈陽市于洪區十一號街|中國|遼寧省|沈陽市|于洪區|水墨*青內 2018:10:24 23:34:06|遼寧省沈陽市于洪區十一號街|中國|遼寧省|沈陽市|于洪區|水墨*青內 2018:10:24 23:12:30|遼寧省沈陽市于洪區十一號街|中國|遼寧省|沈陽市|于洪區|水墨*青內 2017:10:10 07:37:31|廣東省深圳市寶安區澳桂路|中國|廣東省|深圳市|寶安區|尚品*居內 2017:10:10 07:37:36|廣東省深圳市寶安區澳桂路|中國|廣東省|深圳市|寶安區|尚品*居內 2017:10:21 20:28:06|江蘇省徐州市云龍區大工巷1號樓2樓|中國|江蘇省|徐州市|云龍區|建*小區內 2017:10:21 20:22:25|江蘇省徐州市云龍區大工巷1號樓2樓|中國|江蘇省|徐州市|云龍區|建*小區內 2017:11:07 16:02:51|廣東省深圳市寶安區澳桂路|中國|廣東省|深圳市|寶安區|尚品*居內 2017:11:07 16:02:50|廣東省深圳市寶安區澳桂路|中國|廣東省|深圳市|寶安區|尚品*居內 2018:04:04 15:40:21|上海市寶山區春雷路372號|中國|上海市|上海市|寶山區|上海中*醫院內 2018:04:04 15:40:14|上海市寶山區春雷路372號|中國|上海市|上海市|寶山區|上海中*醫院內 2017:10:16 22:42:54|浙江省溫州市永嘉縣|中國|浙江省|溫州市|永嘉縣|西后村附近37米 2018:11:14 21:44:13|廣東省深圳市寶安區寶安大道5005-9|中國|廣東省|深圳市|寶安區|匯*居內 2013:05:13 00:20:17|四川省成都市成華區建設北路2段-4號|中國|四川省|成都市|成華區|電子科技大學(沙河校區)內 2017:10:30 11:47:33|廣東省汕頭市龍湖區長平路東段|中國|廣東省|汕頭市|龍湖區|汕頭龍光喜來*酒店內,龍光世紀大廈南59米 2017:10:30 11:35:11|廣東省汕頭市龍湖區金環南路|中國|廣東省|汕頭市|龍湖區|汕頭龍光喜來*酒店內,龍光世紀大廈內0米 2017:07:28 23:11:27|山東省濟南市濟陽縣緯一路|中國|山東省|濟南市|濟陽縣|雅*園-四區內 2017:07:29 05:20:51|山東省濟南市濟陽縣緯一路|中國|山東省|濟南市|濟陽縣|雅*園-四區內 2017:07:28 23:12:03|山東省濟南市濟陽縣緯一路|中國|山東省|濟南市|濟陽縣|雅*園-四區內 2018:01:09 13:14:27|河北省滄州市任丘市燕山南道|中國|河北省|滄州市|任丘市|源*美璟商業廣場內,源*大酒店內 2017:12:31 11:28:04|浙江省杭州市江干區秋濤北路38號|中國|浙江省|杭州市|江干區|浙江大學醫學院附屬邵逸夫醫院(慶春院區)西南298米 2017:12:31 11:24:09|浙江省杭州市江干區秋濤北路52號3023|中國|浙江省|杭州市|江干區|杭州錢*精品酒店內 2018:01:13 10:47:13|浙江省杭州市上城區浣紗路18號|中國|浙江省|杭州市|上城區|浙江煙草大樓東54米 2017:12:31 11:30:59|浙江省杭州市江干區秋濤北路52號3023|中國|浙江省|杭州市|江干區|杭州錢*精品酒店內 2018:06:21 21:43:45|遼寧省沈陽市于洪區中央大街|中國|遼寧省|沈陽市|于洪區|沈陽世紀高*俱樂部內 2018:08:23 19:04:38|遼寧省沈陽市大東區滂江街|中國|遼寧省|沈陽市|大東區|龍之*暢園內 2018:10:24 23:16:13|遼寧省沈陽市于洪區十一號街|中國|遼寧省|沈陽市|于洪區|水*丹青內 2018:10:24 23:12:40|遼寧省沈陽市于洪區十一號街|中國|遼寧省|沈陽市|于洪區|水*丹青內 2018:10:24 23:34:06|遼寧省沈陽市于洪區十一號街|中國|遼寧省|沈陽市|于洪區|水*丹青內 2018:10:24 23:12:30|遼寧省沈陽市于洪區十一號街|中國|遼寧省|沈陽市|于洪區|水*丹青內 2017:08:07 21:47:14|江蘇省蘇州市張家港市小河壩西路|中國|江蘇省|蘇州市|張家港市|尚*國際內 2017:05:01 23:17:23|江蘇省蘇州市張家港市小河壩西路|中國|江蘇省|蘇州市|張家港市|尚*國際內 2017:05:01 22:56:49|江蘇省蘇州市張家港市小河壩西路|中國|江蘇省|蘇州市|張家港市|尚*國際內 2017:05:01 23:13:07|江蘇省蘇州市張家港市小河壩西路|中國|江蘇省|蘇州市|張家港市|尚*國際內 2017:09:15 09:29:44|陜西省西安市未央區浐灞二路|中國|陜西省|西安市|未央區|滹*小區西69米 2017:09:15 09:25:36|陜西省西安市未央區浐灞二路|中國|陜西省|西安市|未央區|泘*小學內 2017:09:15 09:27:12|陜西省西安市未央區浐灞二路|中國|陜西省|西安市|未央區|滹*錦繡-北區內 2017:09:15 09:25:38|陜西省西安市未央區浐灞二路|中國|陜西省|西安市|未央區|泘沱小學內 2018:08:23 23:06:26|福建省南平市建陽市黃溪路93號|中國|福建省|南平市|建陽市|金*大酒店(上水南路店)內 2017:09:15 21:53:39|四川省成都市成華區和錦路|中國|四川省|成都市|成華區|成都*畔生活酒店(成都火車東站魅力店) 2017:06:30 23:22:51|福建省福州市閩侯縣廣賢路|中國|福建省|福州市|閩侯縣|福建華南*職業學院(旗山校區)內 2017:12:04 00:32:06|福建省福州市倉山區永南路|中國|福建省|福州市|倉山區|領*新城內 2017:08:06 10:07:41|四川省成都市新都區詹家灣路|中國|四川省|成都市|新都區|潤*花園內
4. 拍攝位置分析
利用python的科學庫numpy、數據分析庫panda、繪圖庫matplotlib和數據可視化庫pyecharts,對獲取的不良圖片拍攝位置數據進行處理,分析不良圖片拍攝地分布情況。 本文進對數據進行粗略分析,展示結果僅作一般性觀察分析,不代表筆者任何觀點和傾向。
#代碼在notebook中執行
%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['Simhei']
df = pd.read_csv('gps_address.csv',sep='|')
fig = plt.figure(figsize=(15,20))
data = df["province"].value_counts()
num_of_province = data.values
plt.barh(range(len(num_of_province),0,-1),num_of_province,height=0.7,color='steelblue',alpha=0.8)
plt.title("各省分布情況",fontsize=20)
plt.xlabel("數量",fontsize=15)
plt.ylim(0,len(num_of_province)+1)
plt.yticks(range(len(num_of_province),0,-1),data.index,fontsize=15)
for x,y in enumerate(np.sort(num_of_province)):plt.text(y + 0.5,x + 0.9,'%s' % y,fontsize=18 )
plt.show()
?
province.png
fig = plt.figure(figsize=(15,40))
data = df["city"].value_counts()
num_of_city = data.values
plt.barh(range(len(num_of_city),0,-1),num_of_city,height=0.8,color='steelblue',alpha=0.8)
plt.title("城市分布情況",fontsize=20)
plt.xlabel("數量",fontsize=15)
plt.yticks(range(len(num_of_city),0,-1),data.index,fontsize=15)
plt.ylim(0,len(num_of_city)+2)
for x,y in enumerate(np.sort(num_of_city)):plt.text(y +0.2,x + 0.8,'%s' % y,fontsize=18 )
plt.show()
?
city.png
from pyecharts import Map, Geo
import re
provinces = list(df["province"].value_counts().index)
provinces = [re.sub("壯族自治區|自治區|省|市","",x) for x in provinces]
print(provinces)pro_values = list(df["province"].value_counts().values)
city = list(df["province"].value_counts().index)
city_values = list(df["province"].value_counts().values)geo = Geo("各省分布情況", "", title_color="#fff",title_pos="center", width=1000,height=600, background_color='#404a59')
geo.add("", provinces, pro_values, visual_range=[0, 200], maptype='china',visual_text_color="#fff",symbol_size=10, is_visualmap=True)geo
?
各省分布情況.png
city = list(df["city"].value_counts().index)
city= [re.sub("白族自治州|市","",x) for x in city]
city_values = list(df["city"].value_counts().values)
geo = Geo("城市分布情況", "", title_color="#fff",title_pos="center", width=1000,height=600, background_color='#404a59')
geo.add("", city, city_values, visual_range=[0, 200], maptype='china',visual_text_color="#fff", symbol_size=10, is_visualmap=True)
geo
?
城市分布情況.png
總結
以上是生活随笔 為你收集整理的某少儿不宜网站图片拍摄位置分析,Python批量读取图片GPS位置! 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。