用python找出那些被“標記”的照片
環(huán)境準備
下面的兩個第三方模塊都可以直接通過pip快速安裝,這里使用py36作為運行環(huán)境。
思路
- 遍歷目錄
- 拉取數(shù)據(jù)集合
- 遍歷集合取得exif
- exif信息整理,并獲取實體地址
- 拷貝文件到結(jié)果樣本目錄
- 生成json報告文件
基礎知識
下面是現(xiàn)今相片中會存在與GPS相關的關鍵字,大牛亦可一比帶過~ [參考]
{
"GPSVersionID": "GPS版本",
"GPSLatitudeRef": "南北緯",
"GPSLatitude": "緯度",
"GPSLongitudeRef": "東西經(jīng)",
"GPSLongitude": "經(jīng)度",
"GPSAltitudeRef": "海拔參照值",
"GPSAltitude": "海拔",
"GPSTimeStamp": "GPS時間戳",
"GPSSatellites": "測量的衛(wèi)星",
"GPSStatus": "接收器狀態(tài)",
"GPSMeasureMode": "測量模式",
"GPSDOP": "測量精度",
"GPSSpeedRef": "速度單位",
"GPSSpeed": "GPS接收器速度",
"GPSTrackRef": "移動方位參照",
"GPSTrack": "移動方位",
"GPSImgDirectionRef": "圖像方位參照",
"GPSImgDirection": "圖像方位",
"GPSMapDatum": "地理測量資料",
"GPSDestLatitudeRef": "目標緯度參照",
"GPSDestLatitude": "目標緯度",
"GPSDestLongitudeRef": "目標經(jīng)度參照",
"GPSDestLongitude": "目標經(jīng)度",
"GPSDestBearingRef": "目標方位參照",
"GPSDestBearing": "目標方位",
"GPSDestDistanceRef": "目標距離參照",
"GPSDestDistance": "目標距離",
"GPSProcessingMethod": "GPS處理方法名",
"GPSAreaInformation": "GPS區(qū)功能變數(shù)名",
"GPSDateStamp": "GPS日期",
"GPSDifferential": "GPS修正"
}初始化
考慮到exifread的模塊中有大量的logging輸出,這里將它的level級別調(diào)到最高。 然后下邊的KEY是某站在高德地圖API的時候遺留下來的 我也很尷尬。。就當福利了
import os import time import json import random import logging import requests import exifread logging.basicConfig(level=logging.CRITICAL) KEY = "169d2dd7829fe45690fabec812d05bc3"
主邏輯函數(shù)
def main():
# 預設后綴列表
types = ["bmp", "jpg", "tiff", "gif", "png"]
#結(jié)果數(shù)據(jù)集合
picex = []
# 文件存儲路徑
saves = "$" + input("| SavePath: ").strip()
# 文件搜索路徑 并遍歷所有文件返回文件路徑列表
pools = jpgwalk(input("| FindPath: "), types)
#存儲目錄
savep = "%s/%s" % (os.getcwd().replace("\\", "/"), saves)
if savep in pools:
pools.remove(savep)
# 遍歷數(shù)據(jù)集并獲取exif信息
for path in pools:
res = getEXIF(path)
if res:
picex.append(res)
# 結(jié)果報告
print("| Result %s" % len(picex))
# 如果存在結(jié)果 保存結(jié)果到json并講相關圖片復制到該目錄下
if picex:
#創(chuàng)建目錄
if not os.path.exists(saves):
os.mkdir(saves)
#生成一個4格縮進的json文件
with open("%s/%s.json" % (saves, saves), "wb") as f:
f.write(json.dumps(picex, ensure_ascii=False, indent=4).encode("utf8"))
#copy圖像到該目錄
for item in picex:
source_path = item["Filename"]
with open("%s/%s" % (saves, source_path.split("/")[-1]), "wb") as f_in:
with open(source_path, "rb") as f_out:
f_in.write(f_out.read())遍歷方法
遍歷指定及其所有下級目錄,并返回全部的圖片的路徑集合,這里要注意的是每次掃描后的拷貝行為都會生成緩存,所以通過指定 $ 來避開。
# 獲取指導目錄全部的圖片路徑
def jpgwalk(path, types):
_start = time.time()
_pools = []
# 遍歷該目錄 并判斷files后綴 如符合規(guī)則則拼接路徑
for _root, _dirs, _files in os.walk(path):
_pools.extend([_root.replace("\\", "/") + "/" +
_item for _item in _files if _item.split(".")[-1].lower() in types and "$" not in _root])
#報告消耗時間
print("| Find %s \n| Time %.3fs" % (len(_pools), time.time() - _start))
return _pools經(jīng)緯度格式化
度分秒轉(zhuǎn)浮點,方便api調(diào)用查詢,因為存在一些詭異的數(shù)據(jù)比如 1/0,所以默認返回0
def cg(i):
try:
_ii = [float(eval(x)) for x in i[1:][:-1].split(', ')]
_res = _ii[0] + _ii[1] / 60 + _ii[2] / 3600
return _res
except ZeroDivisionError:
return 0EXIF信息整理
考慮到大部分的設備還未開始支持朝向、速度、測量依據(jù)等關鍵字,這里暫時只使用比較常見的,如有需要的朋友可以自行添加。畢竟得到的信息越多對社工有更大的幫助。
def getEXIF(filepath):
#基礎關鍵字
_showlist = [
'GPS GPSDOP',
'GPS GPSMeasureMode',
'GPS GPSAltitudeRef',
'GPS GPSAltitude',
'Image Software',
'Image Model',
'Image Make'
]
#GPS關鍵字
_XYlist = ["GPS GPSLatitude", "GPS GPSLongitude"]
#時間關鍵字
_TimeList = ["EXIF DateTimeOrigina", "Image DateTime", "GPS GPSDate"]
#初始化結(jié)果字典
_infos = {
'Filename': filepath
}
with open(filepath, "rb") as _files:
_tags = None
# 嘗試去的EXIF信息
try:
_tags = exifread.process_file(_files)
except KeyError:
return
# 判斷是否存在地理位置信息
_tagkeys = _tags.keys()
if _tags and len(set(_tagkeys) & set(_XYlist)) == 2 and cg(str(_tags["GPS GPSLongitude"])) != 0.0:
for _item in sorted(_tagkeys):
if _item in _showlist:
_infos[_item.split()[-1]] = str(_tags[_item]).strip()
# 經(jīng)緯度取值
_infos["GPS"] = (cg(str(_tags["GPS GPSLatitude"])) * float(1.0 if str(_tags.get("GPS GPSLatitudeRef", "N")) == "N" else -1.0),
cg(str(_tags["GPS GPSLongitude"])) * float(1.0 if str(_tags.get("GPS GPSLongitudeRef", "E")) == "E" else -1.0))
# 獲取實體地址
_infos["address"] = address(_infos["GPS"])
# 獲取照片海拔高度
if "GPS GPSAltitudeRef" in _tagkeys:
try:
_infos["GPSAltitude"] = eval(_infos["GPSAltitude"])
except ZeroDivisionError:
_infos["GPSAltitude"] = 0
_infos["GPSAltitude"] = "距%s%.2f米" % ("地面" if int(
_infos["GPSAltitudeRef"]) == 1 else "海平面", _infos["GPSAltitude"])
del _infos["GPSAltitudeRef"]
# 獲取可用時間
_timeitem = list(set(_TimeList) & set(_tagkeys))
if _timeitem:
_infos["Dates"] = str(_tags[_timeitem[0]])
return _infos地址轉(zhuǎn)換
一個簡單的爬蟲,調(diào)用高德地圖api進行坐標轉(zhuǎn)換,考慮到原本是跨域,這里添加基礎的反防爬代碼。這里有個小細節(jié),海外的一律都取不到,可以通過更換googlemap的api來實現(xiàn)全球查詢。
def address(gps):
global KEY
try:
# 隨機UA
_ulist = [
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; InfoPath.2; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; 360SE)",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; Tablet PC 2.0; .NET4.0E)",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)",
"Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040913 Firefox/0.10",
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; ja) Presto/2.10.289 Version/12.00",
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36"
]
# 偽造header
_header = {
"User-Agent": random.choice(_ulist),
"Accept": "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate, sdch",
"Accept-Language": "zh-CN,zh;q=0.8",
"Referer": "http://www.gpsspg.com",
}
_res = requests.get(
"http://restapi.amap.com/v3/geocode/regeo?key={2}&s=rsv3&location={1},{0}&platform=JS&logversion=2.0&sdkversion=1.3&appname=http%3A%2F%2Fwww.gpsspg.com%2Fiframe%2Fmaps%2Famap_161128.htm%3Fmapi%3D3&csid=945C5A2C-E67F-4362-B881-9608D9BC9913".format(gps[0], gps[1], KEY), headers=_header, timeout=(5, 5))
_json = _res.json()
# 判斷是否取得數(shù)據(jù)
if _json and _json["status"] == "1" and _json["info"] == "OK":
# 返回對應地址
return _json.get("regeocode").get("formatted_address")
except Exception as e:
pass實例
運行該代碼 然后輸入保存文件夾名和掃描位置即可

這邊可以看到8019張中有396張存在有效的地理位置,打碼的地方就不解釋了,各位老司機~后期打算加入圖像識別,和相似度識別。

下面給大家分享小編收集整理的python專題知識:
以上所述是小編給大家介紹的用python找出那些被“標記”的照片,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
Python編程實現(xiàn)tail-n查看日志文件的方法
這篇文章主要介紹了Python編程實現(xiàn)tail-n查看日志文件的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-07-07
Python OS系統(tǒng)解決路徑中空格原因?qū)е挛募虿婚_的問題
這篇文章主要介紹了Python OS系統(tǒng)解決路徑中空格原因?qū)е挛募虿婚_的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02
pycharm下查看python的變量類型和變量內(nèi)容的方法
今天小編就為大家分享一篇pycharm下查看python的變量類型和變量內(nèi)容的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06
Appium+Python實現(xiàn)簡單的自動化登錄測試的實現(xiàn)
這篇文章主要介紹了Appium+Python實現(xiàn)簡單的自動化登錄測試的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01
Pycharm代碼無法復制,無法選中刪除,無法編輯的解決方法
今天小編就為大家分享一篇Pycharm代碼無法復制,無法選中刪除,無法編輯的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10
Python中使用Opencv開發(fā)停車位計數(shù)器功能
這篇文章主要介紹了Python中使用Opencv開發(fā)停車位計數(shù)器,本教程最好的一點就是我們將使用基本的圖像處理技術來解決這個問題,沒有使用機器學習、深度學習進行訓練來識別,感興趣的朋友跟隨小編一起看看吧2022-04-04
Python使用Peewee創(chuàng)建數(shù)據(jù)庫的實現(xiàn)示例
Peewee是一個簡單小巧的Python ORM,本文主要介紹了Python使用Peewee創(chuàng)建數(shù)據(jù)庫的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2023-08-08
數(shù)據(jù)可視化Pyecharts的實際使用方式
這篇文章主要介紹了數(shù)據(jù)可視化Pyecharts的實際使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
Pytorch 統(tǒng)計模型參數(shù)量的操作 param.numel()
這篇文章主要介紹了Pytorch 統(tǒng)計模型參數(shù)量的操作 param.numel(),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-05-05

