如何从Instagram Python客户端获取视频?

2 投票
1 回答
1864 浏览
提问于 2025-04-17 21:49

我正在使用Python Instagram Client来从Instagram获取数据。我为了测试创建了一个Instagram账号,里面有三条媒体内容:两张图片和一段视频。在用Python Instagram Client发出请求后,我在python控制台中得到了以下响应(django shell):

>>> recent_media, next = api.user_recent_media()
>>> recent_media
>>> [Media: 673901579909298365_1166496117, Media: 673880146437045009_1166496117, Media: 673827880594143995_1166496117]

我检查了所有的媒体对象,发现里面没有视频的信息,尽管最后一个媒体对象是视频。所有三个对象都有一个叫images的属性;而最后一个媒体对象,尽管是视频,但也有一个images属性,里面包含了不同分辨率的视频快照。在阅读了Instagram的Rest API后,我的理解是最后的媒体对象应该有一个叫videos的属性,里面会是一个字典,视频的信息应该在里面(基本上我想获取的是视频的链接)。

我的问题是:Python Instagram Client是不是过时了,所以根本不返回视频信息,我必须使用Rest API来获取视频信息?还是说我在请求中做错了什么?

提前谢谢你们!

1 个回答

2

你没有做错什么。Instagram的Python接口缺少很多功能,而且还有很多bug。我在自己本地的版本上修复了这些问题,但我没有把这些改动提交到官方的github上,也不确定他们会不会接受这些改动。

一般来说,他们的API客户端在把数据转换回模型时,会把一些数据去掉。我不明白他们为什么不直接用一种可以把字典转换成点符号模型的方法。这个过程完全是手动的,而且我觉得错误很多,代码质量也不高。总之,数据其实是存在的,但在从字典转换成他们自家的API模型时,他们却忽略了这些数据。

我发现你在做的事情中有几个问题:

  1. API媒体模型中没有返回“类型”信息。虽然有一个“类型”属性可以用来检查任何媒体相关的响应,看看是图片还是视频。你可以像我一样自己添加这个属性,或者你可以假设任何有“视频”部分且数据已填充的内容就是视频。

  2. API媒体模型中没有返回“视频”信息。我也是自己添加的。你可以在查看json时找到两个URL,一个是标准分辨率,一个是低分辨率。在处理响应时,这些属性并不总是存在,所以你的代码需要相应地进行检查,比如用get/getattr等方法。

  3. 我认为API中的分页信息也有问题。你应该能得到一个包含几种不同信息的对象,但他们声称其中一部分信息已经过时(我不知道他们为什么在同一个版本的接口中还要返回这些信息)。你得到的唯一信息是用于分页的下一个URL,这在Python API客户端中完全没用。你用Python客户端的目的就是为了避免手动调用和解析REST URL,但这里却返回了一个你必须手动处理的URL。总之,你需要修补API客户端,让它返回正确的模型,或者简单地从URL中解析出这些信息。我最开始选择后者,因为我希望不去修补客户端本身。你还会遇到一个额外的问题,因为某些端点(比如标签)实际上会改变你得到的分页URL中的查询字符串参数,所以你需要根据他们给你的内容进行条件检查。再次强调,这种设计不一致,我认为这不好。

如果你需要,我可以提供所有这些的代码,但如果你想找一种更优雅的方式来修补这些问题,可以看看API中的models.py。我现在不在代码前面,但我可以根据记忆告诉你我做了什么。

  1. 创建一个新的视频模型,继承自媒体模型,就像他们为图片模型所做的那样。

  2. 在读取响应字典的地方,解析出视频并将其添加到响应字典中,就像处理图片一样。记得添加一个前置条件,检查视频键是否缺失,正如我之前提到的。

  3. 解析类型属性并将其添加到响应模型中。

  4. 为分页数据添加一个模型,并将其解析到模型中。如果你愿意,也可以在自己的代码中通过一些查询字符串解析来处理。

如果你完成了以上所有步骤,你应该能够简单地读取“视频”属性并获取两个视频URL。就是这样。信息总是会在响应中返回,只是他们在代码中把它丢掉了。如果你需要,我很乐意提供代码或更多信息。

编辑:这里有一些代码 - 放在API的models.py中的object_from_dictionary里:

    #add the videos
    if "videos" in entry:
        new_media.videos = {}
        for version, version_info in entry['videos'].iteritems():
            new_media.videos[version] = Video.object_from_dictionary(version_info)
    #add the type
    new_media.type = entry.get('type')


    #Add this class as well for the videos....
    class Video(ApiModel):

    def __init__(self, url, width, height):
       self.url = url
       self.height = height
       self.width = width

    def __unicode__(self):
        return "Video: %s" % self.url

撰写回答