下载并在python中编写后,为什么我的图片损坏了?

时间:2015-05-18 17:32:39

标签: python facebook utf-8

前言

这是我关于stackoverflow的第一篇文章,所以如果我搞砸了某个地方,我会道歉。我搜索了互联网和stackoverflow,以解决我的问题,但我找不到任何东西。

情况

我正在制作的是使用我的树莓派创建一个数码相框,它也会自动从我妻子的脸书页面下载图片。幸运的是,我找到了一个正在做类似事情的人:

https://github.com/samuelclay/Raspberry-Pi-Photo-Frame

一个月前,这位先生添加了 download_facebook.py脚本。这就是我需要的!所以几天前我开始研究这个脚本,让它首先在我的Windows环境中运行(在我把它扔到pi之前)。不幸的是,没有特定于该脚本的文档,我缺乏python经验。

基于from urllib import urlopen语句,我可以假设这个脚本是为Python 2.x编写的。这是因为Python 3.x现在是from urlib import request

所以我安装了Python 2.7.9解释器,与尝试使用Python 3.4.3解释器相比,我遇到的问题更少。

问题

我已经获得了从facebook帐户下载图片的脚本;但是,图片已损坏。

以下是问题的图片:http://imgur.com/a/3u7cG

现在,我最初使用的是Python 3.4.3并且我的方法 urlrequest(url)(请参阅帖子底部的代码)以及它如何处理图像数据存在问题。我尝试使用不同的格式解码,如utf-8和utf-16,但根据内容标题,它显示utf-8格式(我认为)。

结论

我不确定问题是下载图片并将图片写入文件

如果有人能帮助我,我将永远感激不尽!也让我知道我将来可以做些什么来改善我的帖子。

提前致谢。

代码

from urllib import urlopen
from json import loads
from sys import argv
import dateutil.parser as dateparser
import logging

# plugin your username and access_token (Token can be get and
# modified in the Explorer's Get Access Token button):
# https://graph.facebook.com/USER_NAME/photos?type=uploaded&fields=source&access_token=ACCESS_TOKEN_HERE
FACEBOOK_USER_ID = "**USER ID REMOVED"
FACEBOOK_ACCESS_TOKEN = "** TOKEN REMOVED - GET YOUR OWN **"

def get_logger(label='lvm_cli', level='INFO'):
    """
    Return a generic logger.
    """
    format = '%(asctime)s - %(levelname)s - %(message)s'
    logging.basicConfig(format=format)
    logger = logging.getLogger(label)
    logger.setLevel(getattr(logging, level))
    return logger

def urlrequest(url):
    """
    Make a url request
    """
    req = urlopen(url)
    data = req.read()
    return data

def get_json(url):
    """
    Make a url request and return as a JSON object
    """
    res = urlrequest(url)
    data = loads(res)
    return data

def get_next(data):
    """
    Get next element from facebook JSON response,
    or return None if no next present.
    """
    try:
        return data['paging']['next']
    except KeyError:
        return None

def get_images(data):
    """
    Get all images from facebook JSON response,
    or return None if no data present.
    """
    try:
        return data['data']
    except KeyError:
        return []

def get_all_images(url):
    """
    Get all images using recursion.
    """
    data = get_json(url)
    images = get_images(data)
    next = get_next(data)

    if not next:
        return images
    else:
        return images + get_all_images(next)

def get_url(userid, access_token):
    """
    Generates a useable facebook graph API url
    """
    root = 'https://graph.facebook.com/'
    endpoint = '%s/photos?type=uploaded&fields=source,updated_time&access_token=%s' % \
                (userid, access_token)
    return '%s%s' % (root, endpoint)

def download_file(url, filename):
    """
    Write image to a file.
    """
    data = urlrequest(url)
    path = 'C:/photos/%s' % filename
    f = open(path, 'w')
    f.write(data)
    f.close()

def create_time_stamp(timestring):
    """
    Creates a pretty string from time
    """
    date = dateparser.parse(timestring)
    return date.strftime('%Y-%m-%d-%H-%M-%S')

def download(userid, access_token):
    """
    Download all images to current directory.
    """
    logger = get_logger()
    url = get_url(userid, access_token)
    logger.info('Requesting image direct link, please wait..')
    images = get_all_images(url)

    for image in images:
        logger.info('Downloading %s' % image['source'])
        filename = '%s.jpg' % create_time_stamp(image['created_time'])
        download_file(image['source'], filename)

if __name__ == '__main__':
    download(FACEBOOK_USER_ID, FACEBOOK_ACCESS_TOKEN)

2 个答案:

答案 0 :(得分:2)

回答有关为什么@ Alastair的评论解决方案有效的问题:

f = open(path, 'wb')

来自https://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files

  

在Windows上,' b'附加到模式后以二进制模式打开文件,所以   还有像' rb',' wb'和' r + b'等模式。 Windows上的Python   区分文本和二进制文件;行尾   文本文件中的字符会在数据时自动更改   被读或写。这种对文件数据的幕后修改   适用于ASCII文本文件,但它会破坏这样的二进制数据   在JPEG或EXE文件中。阅读时要非常小心使用二进制模式   并写这样的文件。在Unix上,附加一个' b'至   模式,所以你可以平台独立使用它为所有二进制文件   文件。

(我在Mac上,这解释了为什么问题没有为我复制。)

答案 1 :(得分:0)

Alastair McCormack发布了一些有用的东西!

他说当你打开文件进行写作时,尝试设置二进制模式:f = open(path, 'wb')

现在可以正确下载图像。有谁知道为什么这有效?