How do you download an image and extract Exif data using Python PIL?

核能气质少年 提交于 2020-04-30 07:35:56

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!