Lonely patients

时光不回头,当下最重要。

Python之Instagram图片爬虫(一)

Hello大家好,许久未见,昨天终于打算再写个爬虫例子,于是今天果断来分享一下成果。
本代码使用Python进行书写。


分析页面

首先我们需要有个翻墙工具,毕竟Instagram早已经是墙外之物了。这里呢,选用了Firefly来作为翻墙的工具。

注意请不要翻墙看一些非法的东西,以免被抓。

然后,我们先打开Instagram网站,确认能打开就表明正常翻墙。由于本期主要爬取图片,所以特意选取了一个美女的Instagram为例子,尺度不高,我们打开Chrome F12的调试功能,点选中Network Tab页。

个人首页

按照惯例,首先检查index页面的HTML文件中是否存在图片链接。

缩略图

这里我们复制class = _mck9w _gvoze _f2mse的字符串去Source Tab页下查找,发现并没有结果,将之拷贝出来,发现里面的内容都是动态生成的。

Source页面下的首页HTML

这就不得不怀疑,是不是所有的数据都以其他形式放在首页HTML文件中,或者通过Ajax异步请求过来。我们从Network中随便拷贝一张图片的链接,如下,然后放到HTML文件中搜索,结果出现了。

notepad++中搜索出了3条记录

搜索记录过程中,我们发现了一个惊喜的地方,那就是被script包裹在里面的windows._shareData,图片的链接就在里面,难得可贵的就是数据格式还是json格式的,我们单独提取出来format一下。

json数据块

真正的图片URL就在nodes数据中,这可是个极大的好消息。

代码

# -*- coding: utf-8 -*-

import json
from lxml import etree
import requests
import click

headers = {
    "Origin": "https://www.instagram.com/",
    "Referer": "https://www.instagram.com/_8_jjini/",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/58.0.3029.110 Safari/537.36",
    "Host": "www.instagram.com",
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "accept-encoding": "gzip, deflate, sdch, br",
    "accept-language": "zh-CN,zh;q=0.8",
    "X-Instragram-AJAX": "1",
    "X-Requested-With": "XMLHttpRequest",
    "Upgrade-Insecure-Requests": "1",
}

BASE_URL = "https://www.instagram.com/_8_jjini/"

proxy = {
    'http': 'http://127.0.0.1:38251',
    'https': 'http://127.0.0.1:38251'
}


def crawl():
    click.echo('start')
    try:
        res = requests.get(BASE_URL, headers=headers, proxies=proxy)
        html = etree.HTML(res.content.decode())
        all_a_tags = html.xpath('//script[@type="text/javascript"]/text()')
        for a_tag in all_a_tags:
            if a_tag.strip().startswith('window'):
                data = a_tag.split('= {')[1][:-1]  # 获取json数据块
                js_data = json.loads('{' + data, encoding='utf-8')
                nodes = js_data["entry_data"]["ProfilePage"][0]["user"]["media"]["nodes"]
                for node in nodes:
                    click.echo(node["display_src"])
                click.echo('ok')
    except Exception as e:
        raise e


if __name__ == '__main__':
    crawl()

运行的结果:

图片的URL

随便打开一条URL

注意了,这里的proxy的配置,只要启动Firefly就能看到的。

代理配置

什么,你说怎么下载?那是下回的事情了,我们都还没有爬取所有的URL呢,你忘了更多那个按钮了吗?大家下回见~~

点赞