[关闭]
@Rays 2017-08-28T20:20:29.000000Z 字数 6509 阅读 2500

使用Python对Instagram做数据分析

语言开发 Python


正文:

本文最初发布于KDnuggets网站,原作者Nour Galaby。本文经授权由InfoQ中文站翻译并分享。

我写此文的目的在于展示以编程的方式使用Instagram的基本方法。我的方法可用于数据分析、计算机视觉以及任何你所能想到的酷炫项目中。

Instagram是最大的图片分享社交媒体平台,每月活跃用户约五亿,每日有九千五百万的图片和视频被上传到Instagram。其数据规模巨大,具有很大的潜能。本文将给出如何将Instagram作为数据源而非一个平台,并介绍在项目中使用本文所给出的开发方法。

API和工具简介

Instagram提供了官方API,但是这些API有些过时,并且当前所提供的功能也非常有限。因此在本文中,我使用了LevPasha提供的非Instagram官方API。该API支持所有关键特性,例如点赞、加粉、上传图片和视频等。它使用Python编写,本文中我只关注数据端的操作。

我推荐使用Jupyter Notebook和IPython。使用官方Python虽然没有问题,但是它不提供图片显示等特性。

安装

你可以使用pip安装该软件库,命令如下:

  1. python -m pip install -e git+https://github.com/LevPasha/Instagram-API-python.git#egg=InstagramAPI

如果系统中尚未安装ffmpeg,那么在Linux上,可以使用如下命令安装:

  1. sudo apt-get install ffmpeg

对于Windows系统,需在Python解释器中运行如下命令:

  1. import imageio
  2. imageio.plugins.ffmpeg.download()

下面使用API,实现登入Instragram:

  1. from InstagramAPI import InstagramAPI
  2. username="YOURUSERNAME"
  3. InstagramAPI = InstagramAPI(username, "YOURPASSWORD")
  4. InstagramAPI.login()

如果登录成功,那么你会收到“登陆成功”的消息。

基本请求

做好上面的准备工作后,我们可以着手实现首次请求:

  1. InstagramAPI.getProfileData()
  2. result = InstagramAPI.LastJson
  1. {u'status': u'ok',
  2. u'user': {u'biography': u'',
  3. u'birthday': None,
  4. u'country_code': 20,
  5. u'email': aaa@hotmail.com',
  6. u'external_url': u'',
  7. u'full_name': u'Nour Galaby',
  8. u'gender': 1,
  9. u'has_anonymous_profile_picture': False,
  10. u'hd_profile_pic_url_info': {u'height': 1080,
  11. u'url': u'https://instagram.fcai2-1.fna.fbcdn.net/t51.2885-1aaa7448121591_1aa.jpg',
  12. u'width': 1080},
  13. u'hd_profile_pic_versions': [{u'height': 320,
  14. u'url': u'https://instagram.fcai2-1.fna.fbcdn.net/t51.2885-19/s320x320/19aa23237_4337448121591_195310aaa32_a.jpg',
  15. u'width': 320},
  16. {u'height': 640,
  17. u'url': u'https://instagram.fcai2-1.fna.fbcdn.net/t51.2885-19/s640x640/19623237_45581744812153_44_a.jpg',
  18. u'width': 640}],
  19. u'is_private': True,
  20. u'is_verified': False,
  21. u'national_number': 122,
  22. u'phone_number': u'+201220',
  23. u'pk': 22412229,
  24. u'profile_pic_id': u'1550239680720880455_22',
  25. u'profile_pic_url': u'https://instagram.fcai2-1.fna.fbcdn.net/t51.2885-19/s150x150/19623237_455817448121591_195310166162_a.jpg',
  26. u'show_conversion_edit_entry': False,
  27. u'username': u'nourgalaby'}}

如上所示,结果是以JSON格式给出的,其中包括了所有请求的数据。

你可以使用正常的键值方式访问结果数据。例如:

你也可以使用工具(例如Notepad++)查看JSON数据,并一探究竟。

获取并查看Instagram时间线

下面让我们实现一些更有用的功能。我们将请求排在时间线最后的帖子,并在Jupyter Notebook中查看。

下面代码实现获取时间线:

  1. InstagramAPI.timelineFeed()

类似于前面的请求实现,我们同样使用LastJson()查看结果。查看结果JSON数据,我们可以看到其中包括一系列称为“条目”的键值。列表中的每个元素保存了时间线上特定帖子的信息,其中包括如下元素:

函数

函数Get_posts_from_list()Get_url()在帖子列表上循环,查找每个帖子中的URL,并附加到我们的空列表中。

上述函数完成后,我们将得到一个URL列表,如下所示:

我们可以使用IPython.display模块查看图片,代码如下:

在IPython Notebook中查看图片是十分有用的功能,我们之后还会使用这些函数去查看结果,敬请继续。

获取最受欢迎的帖子

现在我们已经知道了如何发出基本请求,但是如何实现更复杂的请求呢?下面我们要做一些类似的事情,即如何获取我们的帖子中最受欢迎的。要实现这个目的,首先需要获取当前登录用户的所有帖子,然后将帖子按点赞数排序。

获取用户的所有帖子

要获取所有帖子,我们将使用next_max_idmore_avialable值在结果列表上执行循环。

  1. import time
  2. myposts=[]
  3. has_more_posts = True
  4. max_id=""
  5. while has_more_posts:
  6. InstagramAPI.getSelfUserFeed(maxid=max_id)
  7. if InstagramAPI.LastJson['more_available'] is not True:
  8. has_more_posts = False #stop condition
  9. print "stopped"
  10. max_id = InstagramAPI.LastJson.get('next_max_id','')
  11. myposts.extend(InstagramAPI.LastJson['items']) #merge lists
  12. time.sleep(2) # Slows the script down to avoid flooding the servers
  13. print len(myposts)

保存和加载数据到磁盘

因为上面的请求可能需要很长的时间才能完成,我们并不想在没有必要时运行它,因此好的做法是将结果保存起来,并在继续工作时再次加载。为此,我们将使用Pickle。Pickle可以将任何变量序列化并保存到文件中,进而加载它们。下面给出一个工作例子:

保存:

  1. import pickle
  2. filename=username+"_posts"
  3. pickle.dump(myposts,open(filename,"wb"))

加载:

  1. import pickle
  2. filename="nourgalaby_posts"
  3. myposts=pickle.load(file=open(filename))

按点赞数排序

现在我们得到了一个名称为“myposts”的有序字典。要实现根据字典中的某个键值排序,我们可以使用Lambda表达式,代码如下:

  1. myposts_sorted = sorted(myposts, key=lambda k:
  2. k['like_count'],reverse=True)
  3. top_posts=myposts_sorted[:10]
  4. bottom_posts=myposts_sorted[-10:]

如下代码可以实现和上面一样的显示:

  1. image_urls=get_images_from_list(top_posts)
  2. display_images_from_url(image_urls)

过滤图片

我们可能想要对我们的帖子做一些过滤。例如,可能有的帖子中是视频,但是我们只想要图片帖子。我们可以这样做过滤:

  1. myposts_photos= filter(lambda k: k['media_type']==1, myposts)
  2. myposts_vids= filter(lambda k: k['media_type']==2, myposts)
  3. print len(myposts)
  4. print len(myposts_photos)
  5. print len(myposts_vids)

当然,你可以对结果中的任何变量做过滤,发挥你的创造力吧!

通知

  1. InstagramAPI.getRecentActivity()
  2. get_recent_activity_response= InstagramAPI.LastJson
  3. for notifcation in get_recent_activity_response['old_stories']:
  4. print notifcation['args']['text']

结果可能是:

  1. userohamed3 liked your post.
  2. userhacker32 liked your post.
  3. user22 liked your post.
  4. userz77 liked your post.
  5. userwww77 started following you.
  6. user2222 liked your post.
  7. user23553 liked your post.

仅来自特定用户的通知

现在,我们可以按我们的要求操作并玩转通知。例如,我可以获得来自于特定用户的通知列表:

  1. username="diana"
  2. for notifcation in get_recent_activity_response['old_stories']:
  3. text = notifcation['args']['text']
  4. if username in text:
  5. print text

让我们尝试一些更有意思的操作,例如:得到你被点赞最多的时刻,一天中何时人们点赞最多。要实现这些操作,我们将绘制一个关系图,显示一天中的时刻和你所收到点赞数的关系。

下面的代码绘制了通知的时间日期:

  1. import pandas as pd
  2. df = pd.DataFrame({"date":dates})
  3. df.groupby(df["date"].dt.hour).count().plot(kind="bar",title="Hour" )

正如在此例中所看到的,我在下午六点到十点间得到的点赞最多。如果你了解社交媒体,你就会知道这是高峰使用时间,大多数企业选取此时间段发帖以获得最大的认可度。

获取粉丝和被粉列表

下面我将获取粉丝和跟帖列表,并在列表上执行一些操作。

要使用getUserFollowingsgetUserFollowers这两个函数,你首先需要取得user_id。下面给出了一种获取user_id的方式:

现在你可以如下调用函数。注意,如果粉丝数量非常大,你需要做多次请求(下文将详细介绍)。现在我们做了一次请求去获取粉丝和被粉列表。JSON结果中给出了用户列表,其中包含每个粉丝和被粉者的信息。

  1. InstagramAPI.getUserFollowings(user_id)
  2. print len(InstagramAPI.LastJson['users'])
  3. following_list=InstagramAPI.LastJson['users']
  4. InstagramAPI.getUserFollowers(user_id)
  5. print len(InstagramAPI.LastJson['users'])
  6. followers_list=InstagramAPI.LastJson['users']

如果粉丝数量很大,那么给出的结果可能并非完整列表。

获得所有的粉丝

获得所有粉丝列表类似于获得所有帖子。我们将发出一个请求,然后对结果使用next_max_id键值做迭代处理。

在此感谢Francesc Garcia所提供的支持。

  1. import time
  2. followers = []
  3. next_max_id = True
  4. while next_max_id:
  5. print next_max_id
  6. #first iteration hack
  7. if next_max_id == True: next_max_id=''
  8. _ = InstagramAPI.getUserFollowers(user_id,maxid=next_max_id)
  9. followers.extend ( InstagramAPI.LastJson.get('users',[]))
  10. next_max_id = InstagramAPI.LastJson.get('next_max_id','')
  11. time.sleep(1)
  12. followers_list=followers

对于被粉列表也可以同样做,但是我并不会这样做,因为就我而言,一次请求就足以获取我的所有被粉者。

现在我们得到了JSON格式的所有粉丝和被粉者的列表数据。我将转化该列表为一种对用户更友好的数据类型,即集合,以方便在数据上做一系列的操作。

我只取其中的“username”键值,并在其上使用set()。

  1. user_list = map(lambda x: x['username'] , following_list)
  2. following_set= set(user_list)
  3. print len(following_set)
  4. user_list = map(lambda x: x['username'] , followers_list)
  5. followers_set= set(user_list)
  6. print len(followers_set)

这里我选取了所有用户名的集合。对“full_name”也可同样操作,并且结果更为用户友好。但是结果可能并非唯一,因为一些用户可能没有提供全名。

现在我们得到了两个集合。我们可以做如下操作:

这里我给出了粉丝的一些统计数字。你可以做很多事情,例如保存粉丝列表并稍后做对比,以了解掉粉的情况。

上面我们给出了可对Instagram数据进行的操作。我希望你已经学会了如何使用Instagram API,并具备了一些使用这些API可以做哪些事情的基本想法。敬请关注一下官方API,它们依然在开发中,未来你可以使用它们做更多的事情。如有任何疑问或建议,欢迎联系我。

作者简介: Nour Galaby是一名数据科学狂热者,潜心于数据科学和机器学习。

相关阅读:

查看英文原文: A Guide to Instagramming with Python for Data Analysis

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注