10
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Instagramの写真を全部一気に保存する方法

Last updated at Posted at 2020-04-06

#概要
Instagramの画像を全部一気にダウンロードするコードを書きました。
ログインや画面スクロールの部分は手動にすることで安定した動作が期待できます。

#デモ動画
こんな感じに動きます。

instaimgdownload.gif

⚠️Instagramの利用規約では,自動化された手段を用いて情報を取得する行為は禁止されています。
この記事の内容をもとに自動化ツールを作ることはしないでください。

#Seleniumとは
Selenium とは,Webアプリケーションのテスト自動化に特化した機能を持つツール群です。
詳しくは以前に「Instagramのフォロワーぜんぶ抜く大作戦〜PythonでSeleniumとPyAutoGUIを使いこなす!!〜」という記事で触れているのでご覧ください。

#準備
Python3が使える環境を用意してください。

pip install seleniumでSeleniumをインストールします。

ChromeDriver - WebDriver for Chrome から
いま使っているChromeのversionに対応したChromeDriverをダウンロードします。
Chromeのversionは,Chromeでchrome://version/を検索すると確認できます。便利ですね!

ChromeDriverを最新版にする場合はbrew cask reinstall chromedriverを実行してください。

#コードの流れ
1.Instagramへのログイン
2.画像URLの取得
3.画像のダウンロード

流れなんてどうでもいい,とりあえず動かしたい
という場合は,一番下にコード全体を載せてありますのでどうぞ!

GitHubリポジトリはこちら

##1.Instagramへのログイン

ログインは手動で行ってもらいます。
Instagramアカウントは事前に取得しておいてください。


self.login_time = 20

self.options = webdriver.ChromeOptions()
self.options.add_argument('--no-sandbox')

self.driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', options=self.options)
self.action = ActionChains(self.driver)

def login(self):
    url = "https://www.instagram.com/"
    self.driver.get(url)

    sleep(self.login_time)

options.add_argument('--no-sandbox')を追加することで、実際にログイン画面が別ウインドウで立ち上がります。

ログインにかかる時間はlogin_time = 20で指定します。今回は20秒としました。

##2.画像URLの取得

続いて、画像のURLを取得します。プロフィールページを一番下まで手動でスクロールしてください。

Instagramの仕様上、画面スクロールに対応して表示される画像を取得するようになっています。

動きのイメージがつかみづらい場合は、(CommandOptionI)キーを押すと表示される、デベロッパーツールElementパネルを表示させながら、プロフィールページをスクロールしてみてください。

よくわからない方は,いまの画面のまま(CommandOptionI)キーを押してみてください。
このページのHTMLソースを見ることができるはずです。


self.img_url_list = []

self.window_width = 0
self.window_height = 0

self.scroll_time = 30

def return_img_pattern(self):
    html_source = self.driver.page_source
    pattern = '><a href="/p/(.*?)/"><div class="'
    results = re.findall(pattern, html_source, re.S)
    return results

def fetch_img_url(self, target_username) -> list:
    url = "https://www.instagram.com/{}".format(target_username)
    self.driver.get(url)
    self.driver.maximize_window()

    for i in range(self.scroll_time):
        sleep(1)
        url_list = self.return_img_pattern()
        new_url = [i for i in url_list if i not in self.img_url_list]
        self.img_url_list.extend(new_url)

    return self.img_url_list

スクロールにかかる時間はscroll_time = 30で指定します。今回は30秒としました。

1秒ごとにスクロールで変化したHTMLコードを読み取ります。
この際、正規表現のパターンを使用してHTMLコード中から画像URL(の一部)のみを抜き出します。

##3.画像のダウンロード

最後に、取得した画像URLを使用して、画像を一気にダウンロードします。


self.download_img_size = "l"
#                         l: 640×640px
#                         m: 306×306px
#                         t: 150×150px

def download_img(self, url, save_file_path):
    full_url = "https://www.instagram.com/p/" + str(url) +  "/media/?size=" + self.download_img_size
    r = requests.get(full_url, stream=True)

    if r.status_code == 200:
        with open(save_file_path, 'wb') as f:
            f.write(r.content)

ダウンロードする画像のサイズは、

  • 640×640px
  • 306×306px
  • 150×150px

の中から選べます。download_img_sizeを指定してください。

#全体コード


import re
import json
import requests
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.action_chains  import ActionChains
from selenium.webdriver.common.keys import Keys

class InstaImgCollector:

    def __init__(self):

        self.img_url_list = []
        self.window_width = 0
        self.window_height = 0
        
        self.login_time = 20
        self.scroll_time = 30
        
        self.download_img_size = "l"
#                         l: 640×640px
#                         m: 306×306px
#                         t: 150×150px
        
        self.options = webdriver.ChromeOptions()
        self.options.add_argument('--no-sandbox')

        self.driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', options=self.options)
        self.action = ActionChains(self.driver)
    
    def return_img_pattern(self):
        html_source = self.driver.page_source

        pattern = '><a href="/p/(.*?)/"><div class="'
        results = re.findall(pattern, html_source, re.S)
        return results

    def login(self):
        url = "https://www.instagram.com/"
        self.driver.get(url)

        sleep(self.login_time)

    def fetch_img_url(self, target_username) -> list:
        url = "https://www.instagram.com/{}".format(target_username)
        self.driver.get(url)
        self.driver.maximize_window()
        
        for i in range(self.scroll_time):
            sleep(1)
            url_list = self.return_img_pattern()
            new_url = [i for i in url_list if i not in self.img_url_list]
            self.img_url_list.extend(new_url)
        
        return self.img_url_list
        
    def download_img(self, url, save_file_path):
        full_url = "https://www.instagram.com/p/" + str(url) +  "/media/?size=" + self.download_img_size
        r = requests.get(full_url, stream=True)
        
        if r.status_code == 200:
            with open(save_file_path, 'wb') as f:
                f.write(r.content)
    
    def get_post_url_from_id(self, id_):
        self.login()
        
        self.img_url_list = self.fetch_img_url(target_username=id_)

        self.driver.quit()
        return self.img_url_list
    
    def flatten(self, alist):
        return [ flatten for inner in alist for flatten in inner ]


if __name__ == '__main__':
    id_ = "ここにインスタIDを指定する"
    iic = InstaImgCollector()
    url_list = iic.get_post_url_from_id(id_)
    
    for url_i in url_list:
        iic.download_img(url_i, "img/{}.png".format(url_i))

#参考
InstaImgCollector
Seleniumとは
Selenium webdriverよく使う操作メソッドまとめ
Google Chromeのバージョンを確認する方法【Mac/Windows共通】

10
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?