網路安全和資料分析應用中,取得地理位置和後設資料至關重要。本文介紹如何使用 Python 從 IP 位址、網域名稱、影像和檔案中提取這些資訊。首先,我們會探討使用 geoip2 和 maxminddb-geolite2 函式庫解析 IP 位址和網域名稱地理位置資訊的方法,並比較它們的優缺點。接著,我們將深入研究如何使用 PIL 函式庫從影像中提取 EXIF 後設資料,包含 GPS 資訊的解碼和轉換,提供從圖片中取得地理位置的實用技巧。最後,我們將簡要介紹如何從常見檔案格式中提取後設資料,為讀者提供更全面的資訊提取方案。
從檔案、影像和瀏覽器中提取地理位置和後設資料
後設資料是一系列描述檔案各種資訊的標籤。這些資訊可以根據檔案的建立方式和格式、作者、建立日期和作業系統的不同而有很大差異。
本章涵蓋了Python中用於提取IP地址地理位置資訊、從影像和檔案中提取後設資料以及識別網站所使用的網路技術的主要模組。同時,我們還將介紹如何提取Chrome和Firefox瀏覽器的後設資料,以及與下載、cookie和歷史資料相關的資訊,這些資訊儲存在SQLite資料函式庫中。
技術需求
在開始閱讀本章之前,您應該瞭解Python程式設計的基礎知識,並具備一些關於HTTP的基本知識。我們將使用Python 3.7版本,可在www.python.org/downloads取得。
提取地理位置資訊
在本文中,我們將介紹如何從IP地址或網域名稱中提取地理位置資訊。
一種取得IP地址或網域名稱地理位置資訊的方法是使用提供地理位置資訊的服務,例如hackertarget.com。
使用hackertarget.com取得地理位置資訊
hackertarget.com提供了一個REST API,用於取得IP地址的地理位置資訊,端點為https://api.hackertarget.com/geoip/?q=8.8.8.8。
IP Address: 8.8.8.8
Country: United States
State:
City:
Latitude: 37.751
Longitude: -97.822
使用freegeoip.app取得地理位置資訊
我們可以使用類別似的服務,例如freegeoip.app,來取得地理位置資訊。該服務提供了一個端點,用於透過IP地址取得地理位置資訊:https://freegeoip.app/json/8.8.8.8。
import requests
class IPtoGeo(object):
def __init__(self, ip_address):
self.latitude = ''
self.longitude = ''
self.country = ''
self.city = ''
self.time_zone = ''
self.ip_address = ip_address
self.get_location()
def get_location(self):
json_request = requests.get('https://freegeoip.app/json/%s' % self.ip_address).json()
if 'country_name' in json_request.keys():
self.country = json_request['country_name']
if 'country_code' in json_request.keys():
self.country_code = json_request['country_code']
if 'time_zone' in json_request.keys():
self.time_zone = json_request['time_zone']
if 'city' in json_request.keys():
self.city = json_request['city']
if 'latitude' in json_request.keys():
self.latitude = json_request['latitude']
if 'longitude' in json_request.keys():
self.longitude = json_request['longitude']
if __name__ == '__main__':
ip = IPtoGeo('8.8.8.8')
print(ip.__dict__)
內容解密:
- 匯入requests模組:匯入Python的requests模組,用於傳送HTTP請求。
- 定義IPtoGeo類別:定義一個名為IPtoGeo的類別,用於將IP地址轉換為地理位置資訊。
__init__方法初始化屬性:在__init__方法中,初始化例項屬性,包括經度、緯度、國家、城市、時區和IP地址。get_location方法取得地理位置資訊:使用requests.get方法傳送GET請求到freegeoip.app服務,取得IP地址的地理位置資訊,並將結果儲存在例項屬性中。- 執行指令碼:在
if __name__ == '__main__':區塊中,建立IPtoGeo例項,並列印預出IP地址的地理位置資訊。
輸出結果將類別似於:
{'latitude': 38.7936, 'longitude': -90.7854, 'country': 'United States', 'city': 'Lake Saint Louis', 'time_zone': 'America/Chicago', 'ip_address': '8.8.8.8', 'country_code': 'US'}
從網域名稱取得地理位置資訊
我們也可以使用網域名稱和requests模組來取得地理位置資訊。
import requests
def geoip(domain):
headers = {
"Content-Type": "application/json"
}
response = requests.get('http://freegeoip.app/json/' + domain, headers=headers)
return response.text
print(geoip('python.org'))
內容解密:
- 匯入requests模組:匯入Python的requests模組,用於傳送HTTP請求。
- 定義geoip函式:定義一個名為geoip的函式,用於取得網域名稱的地理位置資訊。
- 設定請求頭:設定請求頭中的Content-Type為application/json。
- 傳送GET請求:使用requests.get方法傳送GET請求到freegeoip.app服務,取得網域名稱的地理位置資訊。
- 傳回回應文字:傳回回應的文字內容。
- 執行函式:呼叫geoip函式,並列印預出python.org的地理位置資訊。
使用Python進行IP地理位置解析的技術探討
在網路安全和資訊探勘的領域中,取得特定IP位址的地理位置資訊是一項重要的任務。本文將探討如何使用Python程式語言,結合多個函式庫來實作IP地理位置的解析。
IP地理位置解析的背景與重要性
隨著網路技術的發展,瞭解網路流量的來源與目的地變得越來越重要。IP地理位置解析技術能夠幫助我們確定特定IP位址對應的物理位置,這對於網路安全監控、內容分發最佳化以及市場研究等多個領域具有重要意義。
常見的IP地理位置解析服務
目前有多種服務提供IP地理位置資訊的查詢,包括但不限於freegeoip、GeoIP2等。這些服務通常提供API介面或資料函式庫下載,使得開發者能夠輕鬆地將地理位置解析功能整合到自己的應用中。
Python中的IP地理位置解析函式庫
在Python生態系統中,有幾個優秀的函式庫可以用於IP地理位置解析,主要包括geoip2和maxminddb-geolite2。
geoip2函式庫的使用
geoip2是一個用於存取GeoIP2網路服務和資料函式庫的Python客戶端。透過geoip2,開發者能夠方便地查詢IP位址對應的地理位置資訊。以下是一個使用geoip2函式庫查詢IP地理位置的範例程式碼:
#!/usr/bin/env python3
import socket
import geoip2.database
import argparse
parser = argparse.ArgumentParser(description='取得IP地理位置資訊')
parser.add_argument('--hostname', action="store", dest="hostname", default='python.org')
given_args = parser.parse_args()
hostname = given_args.hostname
ip_address = socket.gethostbyname(hostname)
reader = geoip2.database.Reader('GeoLite2-City.mmdb')
response = reader.city(ip_address)
print("IP位址:", ip_address)
print('國家:', response.country.names['en'])
print('洲:', response.continent.names['en'])
print('經度:', response.location.longitude)
print('緯度:', response.location.latitude)
內容解密:
- 使用
argparse模組來解析命令列引數,允許使用者指定要查詢的hostname。 - 使用
socket.gethostbyname()函式將hostname轉換為IP位址。 - 初始化
geoip2.database.Reader物件,並載入GeoLite2-City.mmdb資料函式庫。 - 呼叫
reader.city(ip_address)方法查詢指定IP位址的地理位置資訊。 - 輸出查詢結果,包括國家、洲、經度及緯度等資訊。
maxminddb-geolite2函式庫的使用
maxminddb-geolite2是另一個用於存取MaxMindDB的Python擴充套件,它提供了簡單易用的介面來查詢IP地理位置資訊。以下是一個使用maxminddb-geolite2的範例程式碼:
#!/usr/bin/env python3
import socket
from geolite2 import geolite2
import argparse
import json
parser = argparse.ArgumentParser(description='取得IP地理位置資訊')
parser.add_argument('--hostname', action="store", dest="hostname", default='python.org')
given_args = parser.parse_args()
hostname = given_args.hostname
ip_address = socket.gethostbyname(hostname)
reader = geolite2.reader()
response = reader.get(ip_address)
print("IP位址:", ip_address)
print(json.dumps(response, indent=4))
print("洲:", response['continent']['names']['en'])
print("國家:", response['country']['names']['en'])
print("經度:", response['location']['longitude'])
print("緯度:", response['location']['latitude'])
內容解密:
- 同樣使用
argparse來處理命令列引數。 - 使用
geolite2.reader()建立一個讀取器物件。 - 呼叫
reader.get(ip_address)來取得指定IP的地理位置資訊。 - 使用
json.dumps()格式化輸出查詢結果,使其更易讀。 - 輸出特定欄位的值,如洲、國家、經度及緯度等。
從檔案、影像和瀏覽器中提取地理位置和後設資料
緯度:40.8326,經度:-74.1307,時區:“America/New_York”
在輸出結束時,我們總結了地理位置資訊,包括大洲、國家、緯度、經度和時區。
現在我們已經回顧了從IP地址或網域名稱取得地理位置的主要模組,接下來將介紹Python中用於從影像中提取後設資料的主要模組。
從影像中提取後設資料
本文將介紹如何使用PIL模組從影像中提取EXIF後設資料。EXIF(可交換影像檔案格式)是一種為某些型別的影像格式新增後設資料的規範。通常,JPEG和TIFF影像包含此類別後設資料。EXIF標籤通常包含相機的詳細資訊和拍攝影像時使用的設定,但也可以包含更有趣的資訊,如作者版權和地理位置資料。
PIL模組和EXIF簡介
Python Imaging Library(PIL)是Python中用於處理和操作影像的主要模組之一。PIL模組允許我們提取EXIF格式的影像後設資料。
可以使用以下命令安裝PIL:
$ pip3 install Pillow
EXIF是一種規範,定義了在儲存影像時應遵循的規則,並指定了如何在影像和音訊檔案中儲存後設資料。如今,大多數移動裝置和數碼相機都採用了這一規範。
PIL.ExifTags模組允許我們從TAGS和GPSTAGS中提取資訊:
>>> import PIL.ExifTags
>>> help(PIL.ExifTags)
取得影像的EXIF資料
本文將介紹如何使用PIL子模組從影像中取得EXIF後設資料。首先,我們匯入PIL.image和PIL.TAGS模組。然後,我們遍歷結果並列印值。在這個例子中,為了取得EXIF資料,我們使用_getexif()方法。
可以在exiftags資料夾中的get_exif_tags.py檔案中找到以下程式碼:
from PIL import Image
from PIL.ExifTags import TAGS
for (i, j) in Image.open('images/image.jpg')._getexif().items():
print('%s = %s' % (TAGS.get(i), j))
內容解密:
- 匯入必要的模組:
Image和TAGS。 - 使用
Image.open()方法開啟影像檔案。 - 呼叫
_getexif()方法取得EXIF資料。 - 遍歷EXIF資料並使用
TAGS.get()方法解碼標籤。 - 列印解碼後的標籤和對應的值。
透過編寫一些函式,我們可以改進前面的指令碼,從影像路徑傳回EXIF標籤資訊,包括與GPSInfo相關的資訊。可以在exiftags資料夾中的extractDataFromImages.py檔案中找到以下程式碼:
def get_exif_metadata(image_path):
exifData = {}
image = Image.open(image_path)
if hasattr(image, '_getexif'):
exifinfo = image._getexif()
if exifinfo is not None:
for tag, value in exifinfo.items():
decoded = TAGS.get(tag, tag)
exifData[decoded] = value
decode_gps_info(exifData)
return exifData
內容解密:
- 定義函式
get_exif_metadata(),接受影像路徑作為引數。 - 開啟影像檔案並檢查是否存在EXIF資料。
- 如果存在EXIF資料,則遍歷標籤並解碼。
- 將解碼後的資料儲存在
exifData字典中。 - 呼叫
decode_gps_info()函式解碼GPS資訊。
我們可以透過解碼GPSInfo中的資訊來改進相關資訊,將其轉換為緯度-經度值格式。在下面的方法中,我們提供一個EXIF物件作為引數,該物件包含儲存在GPSInfo物件中的資訊,解碼該資訊,並解析與地理參考相關的資料:
def decode_gps_info(exif):
gpsinfo = {}
if 'GPSInfo' in exif:
Nsec = exif['GPSInfo'][2][2]
Nmin = exif['GPSInfo'][2][1]
Ndeg = exif['GPSInfo'][2][0]
Wsec = exif['GPSInfo'][4][2]
Wmin = exif['GPSInfo'][4][1]
Wdeg = exif['GPSInfo'][4][0]
if exif['GPSInfo'][1] == 'N':
Nmult = 1
else:
Nmult = -1
if exif['GPSInfo'][1] == 'E':
Wmult = 1
else:
Wmult = -1
latitude = Nmult * (Ndeg + (Nmin + Nsec/60.0)/60.0)
longitude = Wmult * (Wdeg + (Wmin + Wsec/60.0)/60.0)
exif['GPSInfo'] = {"Latitude": latitude, "Longitude": longitude}
內容解密:
- 定義函式
decode_gps_info(),接受EXIF資料作為引數。 - 檢查EXIF資料中是否存在GPSInfo。
- 如果存在GPSInfo,則提取相關資訊並計算緯度和經度。
- 將計算出的緯度和經度儲存在
exif['GPSInfo']中。