问题
I am trying to read the Exif data from a downloaded image. I save the image to my computer in one function then try to read the data in another function, but I keep getting a bad mode error. I have been able to read the data from a pre saved image and just used ._getexif() but when I try to do the same thing with the image I download it does not work. What am I doing wrong?
Here is the loop that calls the two functions.
else:
imgTags = findImages(url)
for imgTag in imgTags:
imgFileName = downloadImage(imgTag)
testForExif(imgFileName)
Find and download images from the page
def findImages(url):
print '[*] Finding images on ' + url
urlContent = urllib2.urlopen(url).read()
soup = BeautifulSoup(urlContent)
imgTags = soup.findAll('img')
return imgTags
def downloadImage(imgTag):
try:
print '[+] Downloading image...'
imgSrc = imgTag['src']
imgContent = urllib2.urlopen(imgSrc).read()
imgFileName = basename(urlsplit(imgSrc)[2])
imgFile = open(imgFileName, 'wb')
imgFile.write(imgContent)
imgFile.close()
return imgFileName
except:
return ''
Read for exif data
def testForExif(imgFileName):
exifData = {}
imgFile = Image.open(imgFileName, 'rb')
info = imgFile._getexif()
print '\n\n' + str(info) + '\n\n'
if info:
for (tag, value) in info.items():
decoded = TAGS.get(tag, tag)
exifData[decoded] = value
exifGPS = exifData['GPSInfo']
if exifGPS:
print '[+] ' + imgFileName + ' contains GPS MetaData'
I believe the 'bad mode' error is triggered in teh testsForExif function, somewhere in the first couple of lines. It never makes it to the first print statement.
The exact error I am getting is.
ValueError: Bad Mode
Traceback (most recent call last): File "C:\Users\HeyNow\Downloads\Python\Cookbook\Forensics\metaurl.py", line 59 , in main() File "C:\Users\HeyNow\Downloads\Python\Cookbook\Forensics\metaurl.py", line 56 , in main testForExif(imgFileName) File "C:\Users\HeyNow\Downloads\Python\Cookbook\Forensics\metaurl.py", line 31 , in testForExif imgFile = Image.open(imgFileName, 'rb') File "C:\Python27\lib\site-packages\PIL\Image.py", line 1947, in open raise ValueError("bad mode") ValueError: bad mode
From playing around with it I have also gotten a.
Bad Mode 'rb', filename;
Error as well.
I'm lost.
EDIT: If I change:
imgFile = Image.open(imgFileName, 'rb')
to
imgFile = Image.open(imgFileName)
I get AttributeError: _getexif()
Traceback:
Traceback (most recent call last): File "C:\Users\HeyNow\Downloads\Python\Cookbook\Forensics\metaurl.py", line 59 , in main() File "C:\Users\HeyNow\Downloads\Python\Cookbook\Forensics\metaurl.py", line 56 , in main testForExif(imgFileName) File "C:\Users\HeyNow\Downloads\Python\Cookbook\Forensics\metaurl.py", line 32 , in testForExif info = imgFile._getexif() File "C:\Python27\lib\site-packages\PIL\Image.py", line 512, in getattr raise AttributeError(name) AttributeError: _getexif
回答1:
I think you are getting errors because of the way "downloadImages" works. You are just returning an empty string in the event that there are any sort of errors. However, back in your testforexif you don't check to see if the filename is not an empty string before attempting to open it.
Image.open('')
will cause imgfile to be None. So then it has no attributes and you get the attribute error.
There is probably some error in your parsing of the webpage or processing of the filenames that is throwing errors. It is very bad form to not properly handle errors and in this case it is causing your program not to function at all. You have the try/except statement but you simply proceed even if there are errors. What you need to do is change the except clause to skip that filename if there are errors (or it is null). Hope that helps.
EDIT:
Try printing your variables as you go (such as the filenames) just to make sure that they are correct and the images exist. It may also be an issue of filetypes. For example, perhaps your script is finding some non-jpg image files and is trying to open the exif data on a bmp or what have you.
回答2:
You don't need too define rb
mode just simply use:
Image.open(imgFileName)
The only mode Image.open()
accept is r
mode (which is default). See here
来源:https://stackoverflow.com/questions/24370527/how-do-you-download-an-image-and-extract-exif-data-using-python-pil