大家都知道Instagram上面有很多漂亮妹纸晒图啊,或者是一些值得一观的摄影图啊。但是有时候这些个po主突然就不见了,要么就是账户被xx了。所以看到“好看”的图片保存下来才是王道啊。
本文通过python脚本实现图片的爬取及下载。
爬取又分为两个部分,一种是爬取某个用户的全部照片;另外一种就是只下载单张图片。各有各的好处吧,全部下载慢慢自己筛选也是可以,只下载自己觉得OK的也可以。
环境设置
爬取的前提是你已经能够正常访问https://www.instagram.com,如果你点击这个网址不正常的话,那说明你还需要通过设置代理来实现访问了(如果代理都不知道的话,那就可以关掉本页面了。)
有时候即使用了代理,也会出现图片无法加载的问题,一般这种情况是Instagram的图片实际保存位置在它的cdn服务器上,所以要将该cdn域名也加入到规则里面。
cdninstagram.com
好了,到目前为止,你大概已经可以正常访问和浏览图片了,我们可以开始接着往下了。
爬取单张图片
首先,我们来看一下Instagram的图片页面地址:
https://www.instagram.com/p/BndYOdaDqKo
BndYOdaDqKo
:这个就是图片页面的短码,用来标识Instagram的单个页面。
在chrome浏览器中用F12来审查元素可以看到图片的url:
在图片区域的srcset
参数中设置了图片的地址,如下:
https://scontent-lax3-1.cdninstagram.com/vp/f584a4a90b6d24c764f8c236fda39a1f/5D03F4BB/t51.2885-15/sh0.08/e35/p640x640/40191912_869314559941371_6970807043603770521_n.jpg?_nc_ht=scontent-lax3-1.cdninstagram.com 640w,
https://scontent-lax3-1.cdninstagram.com/vp/f3e6ba2636649a5f545e464b8868a137/5D13F7BB/t51.2885-15/sh0.08/e35/p750x750/40191912_869314559941371_6970807043603770521_n.jpg?_nc_ht=scontent-lax3-1.cdninstagram.com 750w,
https://scontent-lax3-1.cdninstagram.com/vp/44d70ff4fe95a05ad757e78268a428d1/5D154C4D/t51.2885-15/e35/40191912_869314559941371_6970807043603770521_n.jpg?_nc_ht=scontent-lax3-1.cdninstagram.com 1080w
上面的链接后面说明了图片的质量。当然,下载的话,肯定是下载质量最好的,1080w。
到这里,我们就得到了图片的url地址了,可以直接在浏览器访问,然后右键保存。那么教程是不是到这里就结束了? 当然不是,我们得放弃这种手工方式,采用脚本自动的方式。
下一步就是分析页面源码,也就是通过实际我们通过脚本get出来的页面数据了。
直接在该页面右键查看网页源码(或者Ctrl U),然后将我们上面得到的图片url搜索一下
在这一段js脚本中匹配到了,也就是说我们刚刚通过审查元素方式查看的url实际上是通过这部分数据显示的,再仔细分析这种js代码实际上就是一段json数据。而且display_url
这个字段的图片url质量就是最好的,也就是我们可以通过这个字段来获取对应的图片url。
直接上代码
def crawl_single(short_code):
base_url = 'https://www.instagram.com/p/'
single_page = base_url + short_code
print('single_page:', single_page)
try:
html = get_webpage_text(single_page)
all_a_tags = html.xpath('//script[@type="text/javascript"]/text()')
for a_tag in all_a_tags:
if a_tag.strip().startswith('window._sharedData'):
data = a_tag.split('= ')
json_data = data[1][:-1]
# with open('json_data.txt', 'w') as f:
# f.write(json_data)
# 将JSON字符串转换为字典
dict_data = json.loads(json_data, encoding='utf-8')
# print(dict_data)
# 这里处理字典嵌套的情况
# ================================
# 图片url地址
img_url = dict_data["entry_data"]["PostPage"][0]["graphql"]["shortcode_media"]["display_url"]
# print('img_url:', img_url)
download_image('default', img_url)
except Exception as e:
print("获取图片页面失败!")
return
主要就是获取到对应的json数据,然后转换为字段,直接通过字典获取对应字段值就ok了。
使用如下方式调用该接口:
crawl_single('BndYOdaDqKo') //这里就是url中的短码
另外,如果你是在Instagram App上面复制的链接,有可能长这样:
https://www.instagram.com/p/Bu1kSFFF9Ad/?utm_source=ig_share_sheet&igshid=xcb6kdtrg1si
实际上一样的,只需要Bu1kSFFF9Ad
这个短码即可。它的这个链接等同于
https://www.instagram.com/p/Bu1kSFFF9Ad
爬取用户全部图片
后续有时间再更新吧,有人想要的话可以留言,人多的话,再写写。。。