使用 Python API 上传图片到 facebook

Upload image to facebook using the Python API

我在网上广泛搜索了通过 Python API (Python for Facebook) 将照片上传到 facebook 的仍然有效的示例。像这样的问题以前在 Whosebug 上被问过,但我找到的答案都没有用了。

我得到的工作是:

import facebook as fb

cfg = {
    "page_id"      : "my_page_id",
    "access_token" : "my_access_token"
    }

api = get_api(cfg)
msg = "Hello world!"
status = api.put_wall_post(msg) 

我将 get_api(cfg) 函数定义为这个

graph = fb.GraphAPI(cfg['access_token'], version='2.2')

# Get page token to post as the page. You can skip
# the following if you want to post as yourself.
resp = graph.get_object('me/accounts')
page_access_token = None
for page in resp['data']:
    if page['id'] == cfg['page_id']:
        page_access_token = page['access_token']
graph = fb.GraphAPI(page_access_token)
return graph

这确实 post 向我的 页面 发送了 消息 。 但是,如果我想上传图片,一切都会出错。

# Upload a profile photo for a Page.
api.put_photo(image=open("path_to/my_image.jpg",'rb').read(), message='Here's my image')

我遇到了可怕的 GraphAPIError: (#324) Requires upload file Whosebug 上的所有解决方案都不适合我。 如果我改为发出以下命令

api.put_photo(image=open("path_to/my_image.jpg",'rb').read(), album_path=cfg['page_id'] + "/picture")

我收到 GraphAPIError: (#1) Could not fetch picture 我也找不到解决方案。

有人可以给我指出正确的方向,为我提供一个当前有效的例子吗?将不胜感激,谢谢!

324 Facebook 错误可能由一些原因引起,具体取决于照片上传调用的方式

  • 缺少一张图片
  • Facebook 无法识别的图片
  • 目录路径引用不正确

原始 cURL 调用看起来像

curl -F 'source=@my_image.jpg' 'https://graph.facebook.com/me/photos?access_token=YOUR_TOKEN'

只要上述调用有效,您就可以确定照片与 Facebook 服务器一致。

324 错误如何发生的示例

touch meow.jpg

curl -F 'source=@meow.jpg' 'https://graph.facebook.com/me/photos?access_token=YOUR_TOKEN'

如您所见,损坏的图像文件也可能发生这种情况。

使用.read()将转储实际数据

空文件

>>> image=open("meow.jpg",'rb').read()
>>> image
''

图像文件

>>> image=open("how.png",'rb').read()
>>> image
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00...

如您所见,这两个都不适用于 api.put_photo 调用,Klaus D. 提到调用应该没有 read()

所以这个调用

api.put_photo(image=open("path_to/my_image.jpg",'rb').read(), message='Here's my image')

实际上变成了

api.put_photo('\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00...', message='Here's my image')

这只是一个字符串,这不是我们想要的。

需要图片参考<open file 'how.png', mode 'rb' at 0x1085b2390>

我知道这是旧的,并没有回答指定的问题 API,但是,我通过搜索找到了这个问题,希望我的解决方案能帮助旅行者走上类似的道路。

使用 requeststempfile

我如何使用 tempfile and requests 模块的快速示例。

下载图片并上传到 Facebook

下面的脚本应该从给定的 url 抓取图像,将其保存到临时目录中的文件并在完成后自动清理。

In addition, I can confirm this works running on a Flask service on Google Cloud Run. That comes with the container runtime contract so that we can store the file in-memory.

import tempfile
import requests

# setup stuff - certainly change this
filename = "your-desired-filename"           
filepath = f"{directory}/{filename}"
image_url = "your-image-url"
act_id = "your account id"
access_token = "your access token"

# create the temporary directory
temp_dir = tempfile.TemporaryDirectory()
directory = temp_dir.name

# stream the image bytes
res = requests.get(image_url, stream=True)
# write them to your filename at your temporary directory 
# assuming this works
# add logic for non 200 status codes
with open(filepath, "wb+") as f:
        f.write(res.content)

# prep the payload for the facebook call           
files = {
    "filename": open(filepath, "rb"),
}
url = f"https://graph.facebook.com/v10.0/{act_id}/adimages?access_token={access_token}"
# send the POST request
res = requests.post(url, files=files)
res.raise_for_status()
if res.status_code == 200:
    # get your image data back
    image_upload_data = res.json()
    temp_dir.cleanup()
    if "images" in image_upload_data:
        return image_upload_data["images"][filepath.split("/")[-1]]
    return image_upload_data
temp_dir.cleanup() # paranoid: just in case an error isn't raised