本文最初发布于 KDnuggets 网站,原作者 Nour Galaby 。本文经授权由 InfoQ 中文站翻译并分享。
我写此文的目的在于展示以编程的方式使用 Instagram 的基本方法。我的方法可用于数据分析、计算机视觉以及任何你所能想到的酷炫项目中。
Instagram 是最大的图片分享社交媒体平台,每月活跃用户约五亿,每日有九千五百万的图片和视频被上传到 Instagram。其数据规模巨大,具有很大的潜能。本文将给出如何将 Instagram 作为数据源而非一个平台,并介绍在项目中使用本文所给出的开发方法。
API 和工具简介
Instagram 提供了官方 API,但是这些 API 有些过时,并且当前所提供的功能也非常有限。因此在本文中,我使用了 LevPasha 提供的非 Instagram 官方 API 。该 API 支持所有关键特性,例如点赞、加粉、上传图片和视频等。它使用 Python 编写,本文中我只关注数据端的操作。
我推荐使用 Jupyter Notebook 和 IPython。使用官方 Python 虽然没有问题,但是它不提供图片显示等特性。
安装
你可以使用 pip 安装该软件库,命令如下:
python -m pip install -e git+https://github.com/LevPasha/Instagram-API-python.git#egg=InstagramAPI
如果系统中尚未安装 ffmpeg,那么在 Linux 上,可以使用如下命令安装:
sudo apt-get install ffmpeg
对于 Windows 系统,需在 Python 解释器中运行如下命令:
import imageio imageio.plugins.ffmpeg.download()
下面使用 API,实现登入 Instragram:
from InstagramAPI import InstagramAPI username="YOURUSERNAME" InstagramAPI = InstagramAPI(username, "YOURPASSWORD") InstagramAPI.login()
如果登录成功,那么你会收到“登陆成功”的消息。
基本请求
做好上面的准备工作后,我们可以着手实现首次请求:
InstagramAPI.getProfileData() result = InstagramAPI.LastJson
{u'status': u'ok', u'user': {u'biography': u'', u'birthday': None, u'country_code': 20, u'email': aaa@hotmail.com', u'external_url': u'', u'full_name': u'Nour Galaby', u'gender': 1, u'has_anonymous_profile_picture': False, u'hd_profile_pic_url_info': {u'height': 1080, u'url': u'https://instagram.fcai2-1.fna.fbcdn.net/t51.2885-1aaa7448121591_1aa.jpg', u'width': 1080}, u'hd_profile_pic_versions': [{u'height': 320, u'url': u'https://instagram.fcai2-1.fna.fbcdn.net/t51.2885-19/s320x320/19aa23237_4337448121591_195310aaa32_a.jpg', u'width': 320}, {u'height': 640, u'url': u'https://instagram.fcai2-1.fna.fbcdn.net/t51.2885-19/s640x640/19623237_45581744812153_44_a.jpg', u'width': 640}], u'is_private': True, u'is_verified': False, u'national_number': 122, u'phone_number': u'+201220', u'pk': 22412229, u'profile_pic_id': u'1550239680720880455_22', u'profile_pic_url': u'https://instagram.fcai2-1.fna.fbcdn.net/t51.2885-19/s150x150/19623237_455817448121591_195310166162_a.jpg', u'show_conversion_edit_entry': False, u'username': u'nourgalaby'}}
如上所示,结果是以 JSON 格式给出的,其中包括了所有请求的数据。
你可以使用正常的键值方式访问结果数据。例如:
(点击放大图像)
你也可以使用工具(例如 Notepad++)查看 JSON 数据,并一探究竟。
获取并查看 Instagram 时间线
下面让我们实现一些更有用的功能。我们将请求排在时间线最后的帖子,并在 Jupyter Notebook 中查看。
下面代码实现获取时间线:
InstagramAPI.timelineFeed()
类似于前面的请求实现,我们同样使用 LastJson() 查看结果。查看结果 JSON 数据,我们可以看到其中包括一系列称为“条目”的键值。列表中的每个元素保存了时间线上特定帖子的信息,其中包括如下元素:
- [text]:保存了标题下的帖子文本内容,包括 hashtag。
- [likes]:帖子中的点赞数。
- [created_at]:帖子创建时间。
- [comments]:帖子的评论。
- [image_versions]:保存有指向实际 JPG 文件的链接,可使用该链接在 Jupyter Notebook 中显示图片。
函数
函数 Get_posts_from_list() 和 Get_url() 在帖子列表上循环,查找每个帖子中的 URL,并附加到我们的空列表中。
上述函数完成后,我们将得到一个 URL 列表,如下所示:
(点击放大图像)
我们可以使用IPython.display 模块查看图片,代码如下:
(点击放大图像)
(点击放大图像)
在 IPython Notebook 中查看图片是十分有用的功能,我们之后还会使用这些函数去查看结果,敬请继续。
获取最受欢迎的帖子
现在我们已经知道了如何发出基本请求,但是如何实现更复杂的请求呢?下面我们要做一些类似的事情,即如何获取我们的帖子中最受欢迎的。要实现这个目的,首先需要获取当前登录用户的所有帖子,然后将帖子按点赞数排序。
获取用户的所有帖子
要获取所有帖子,我们将使用 next_max_id 和 more_avialable 值在结果列表上执行循环。
import time myposts=[] has_more_posts = True max_id="" while has_more_posts: InstagramAPI.getSelfUserFeed(maxid=max_id) if InstagramAPI.LastJson['more_available'] is not True: has_more_posts = False #stop condition print "stopped" max_id = InstagramAPI.LastJson.get('next_max_id','') myposts.extend(InstagramAPI.LastJson['items']) #merge lists time.sleep(2) # Slows the script down to avoid flooding the servers print len(myposts)
保存和加载数据到磁盘
因为上面的请求可能需要很长的时间才能完成,我们并不想在没有必要时运行它,因此好的做法是将结果保存起来,并在继续工作时再次加载。为此,我们将使用 Pickle。Pickle 可以将任何变量序列化并保存到文件中,进而加载它们。下面给出一个工作例子:
保存:
import pickle filename=username+"_posts" pickle.dump(myposts,open(filename,"wb"))
加载:
import pickle filename="nourgalaby_posts" myposts=pickle.load(file=open(filename))
按点赞数排序
现在我们得到了一个名称为“myposts”的有序字典。要实现根据字典中的某个键值排序,我们可以使用 Lambda 表达式,代码如下:
myposts_sorted = sorted(myposts, key=lambda k: k['like_count'],reverse=True) top_posts=myposts_sorted[:10] bottom_posts=myposts_sorted[-10:]
如下代码可以实现和上面一样的显示:
image_urls=get_images_from_list(top_posts) display_images_from_url(image_urls)
过滤图片
我们可能想要对我们的帖子做一些过滤。例如,可能有的帖子中是视频,但是我们只想要图片帖子。我们可以这样做过滤:
myposts_photos= filter(lambda k: k['media_type']==1, myposts) myposts_vids= filter(lambda k: k['media_type']==2, myposts) print len(myposts) print len(myposts_photos) print len(myposts_vids)
当然,你可以对结果中的任何变量做过滤,发挥你的创造力吧!
通知
InstagramAPI.getRecentActivity() get_recent_activity_response= InstagramAPI.LastJson for notifcation in get_recent_activity_response['old_stories']: print notifcation['args']['text'] {1}
结果可能是:
userohamed3 liked your post. userhacker32 liked your post. user22 liked your post. userz77 liked your post. userwww77 started following you. user2222 liked your post. user23553 liked your post.
仅来自特定用户的通知
现在,我们可以按我们的要求操作并玩转通知。例如,我可以获得来自于特定用户的通知列表:
username="diana" for notifcation in get_recent_activity_response['old_stories']: text = notifcation['args']['text'] if username in text: print text
让我们尝试一些更有意思的操作,例如:得到你被点赞最多的时刻,一天中何时人们点赞最多。要实现这些操作,我们将绘制一个关系图,显示一天中的时刻和你所收到点赞数的关系。
下面的代码绘制了通知的时间日期:
import pandas as pd df = pd.DataFrame({"date":dates}) df.groupby(df["date"].dt.hour).count().plot(kind="bar",title="Hour" )
(点击放大图像)
正如在此例中所看到的,我在下午六点到十点间得到的点赞最多。如果你了解社交媒体,你就会知道这是高峰使用时间,大多数企业选取此时间段发帖以获得最大的认可度。
获取粉丝和被粉列表
下面我将获取粉丝和跟帖列表,并在列表上执行一些操作。
要使用getUserFollowings 和getUserFollowers 这两个函数,你首先需要取得user_id。下面给出了一种获取user_id 的方式:
(点击放大图像)
现在你可以如下调用函数。注意,如果粉丝数量非常大,你需要做多次请求(下文将详细介绍)。现在我们做了一次请求去获取粉丝和被粉列表。JSON 结果中给出了用户列表,其中包含每个粉丝和被粉者的信息。
InstagramAPI.getUserFollowings(user_id) print len(InstagramAPI.LastJson['users']) following_list=InstagramAPI.LastJson['users'] InstagramAPI.getUserFollowers(user_id) print len(InstagramAPI.LastJson['users']) followers_list=InstagramAPI.LastJson['users']
如果粉丝数量很大,那么给出的结果可能并非完整列表。
获得所有的粉丝
获得所有粉丝列表类似于获得所有帖子。我们将发出一个请求,然后对结果使用 next_max_id 键值做迭代处理。
在此感谢 Francesc Garcia 所提供的支持。
import time followers = [] next_max_id = True while next_max_id: print next_max_id #first iteration hack if next_max_id == True: next_max_id='' _ = InstagramAPI.getUserFollowers(user_id,maxid=next_max_id) followers.extend ( InstagramAPI.LastJson.get('users',[])) next_max_id = InstagramAPI.LastJson.get('next_max_id','') time.sleep(1) followers_list=followers
对于被粉列表也可以同样做,但是我并不会这样做,因为就我而言,一次请求就足以获取我的所有被粉者。
现在我们得到了 JSON 格式的所有粉丝和被粉者的列表数据。我将转化该列表为一种对用户更友好的数据类型,即集合,以方便在数据上做一系列的操作。
我只取其中的“username”键值,并在其上使用 set()。
user_list = map(lambda x: x['username'] , following_list) following_set= set(user_list) print len(following_set) user_list = map(lambda x: x['username'] , followers_list) followers_set= set(user_list) print len(followers_set)
这里我选取了所有用户名的集合。对“full_name”也可同样操作,并且结果更为用户友好。但是结果可能并非唯一,因为一些用户可能没有提供全名。
现在我们得到了两个集合。我们可以做如下操作:
(点击放大图像)
这里我给出了粉丝的一些统计数字。你可以做很多事情,例如保存粉丝列表并稍后做对比,以了解掉粉的情况。
上面我们给出了可对Instagram 数据进行的操作。我希望你已经学会了如何使用Instagram API,并具备了一些使用这些API 可以做哪些事情的基本想法。敬请关注一下官方API,它们依然在开发中,未来你可以使用它们做更多的事情。如有任何疑问或建议,欢迎联系我。
作者简介
Nour Galaby 是一名数据科学狂热者,潜心于数据科学和机器学习。
相关阅读
查看英文原文: A Guide to Instagramming with Python for Data Analysis
感谢蔡芳芳对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论