Download Instagram Photos and Videos Based on User id and Hashtag Using Python and Flask

This article is about to download unlimited Instagram photos and videos from an user id or hashtag using Python 3 and Flask. If you’re looking for an easy Instagram downloader with nice and clean user interface then this tutorial is perfect for you. It will download all public Instagram user’s photos and videos within the same tool directory, and when you run the tool, it will automatically open with a web browser and you will be able to start using the tool immediately. Flask app can run on cloud server, you can easily deploy this script on cloud and it will work as same like on local. So let’s begin…

Prerequisites

To complete this tutorial, we will be using PyCharm IDE with Python 3.7+ installed

Instagram Scraper – main script to download photos and videos

Flask – making web user interface

Installing dependencies

First you need to create new project for example instagram-downloader on pycharm ide with new virtualenv interpreter. After that go to File > Settings and click on Project Interpreter

Click on “+” button (see above screenshot) and type instagram-scraper and click on Install Package

By using the same way, install Flask. If you done it successfully, you’re good to go next.

Creating Project Structure

Make new empty file called app.py

Make a folder within the same directory called templates within the template folder create a html file called index.html

within the template folder create a html file called Make another folder called static, within this folder create another folder called css and js. Inside css folder create a css file called style.css

All files and folders look like this

Step 1

Open index.html file from templates folder and put these code

<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" type="text/css" rel="stylesheet" /> <link href="{{ url_for('static', filename='css/style.css') }}" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script> <title>IG Downloader</title> <script> $(document).ready(function() { $("#hashtag").hide(); $("#download_type").change(function() { ($(this).val() == "by_user") ? $("#user").show() : $("#user").hide(); ($(this).val() == "by_hashtag") ? $("#hashtag").show() : $("#hashtag").hide(); }); $("#submit").click(function(){ var user_id_val = $(".user").val(); var hashtag_val = $(".hashtag").val(); if (user_id_val.length || hashtag_val.length) { $("#loading").css("display", "block"); $("#main-content").hide() } $(".alert-danger").css("display", "block") }); }); </script> </head> <body> <div class="gradient-overlay-half-primary-v1 bg-img-hero""> <div class="container space-2 space-4-top--lg space-3-bottom--lg"> <div class="row align-items-lg-center"> <div class="col-lg-7"> <form method="post" class=""> <div class="form-group"> <label class="form-label text-white">Select Download Type</label> <select id="download_type" name="download_type" class="form-control"> <option value="by_user">by User id</option> <option value="by_hashtag">by Hashtag</option> </select> </div> <div class="form-group" id="user"> <label class="form-label text-white">Insert user id to download, for multi user downloads, put user ids separated by " , "</label> <input type="text" name="user" class="form-control user" placeholder="user1,user2,user3"> </div> <div class="form-group" id="hashtag"> <label class="form-label text-white">Hashtag wihtout # ex: instagram</label> <input type="text" name="hashtag" class="form-control hashtag" placeholder="instagram"> </div> <div class="form-group"> <label class="form-label text-white">Select Media Type</label> <select id="media_type" name="media_type" class="form-control"> <option value="">All</option> <option value="image">Image</option> <option value="video">Video</option> </select> </div> <div class="form-group"> <label class="form-label text-white">Select Download Items</label> <select id="amount" name="amount" class="form-control"> <option value="10">10</option> <option value="20">20</option> <option value="50">50</option> <option value="100">100</option> <option value="200">200</option> <option value="300">300</option> <option value="500">500</option> <option value="1000">1000</option> <option value="1500">1500</option> <option value="2000">2000</option> <option value="3000">3000</option> <option value="4000">4000</option> <option value="5000">5000</option> </select> </div> <div class="search_option_button"> <button name="submit" type="submit" id="submit" class="btn btn-thm btn-secondary h70">Download</button> </div> </form> </div> <div class="col-lg-5"> <div class="product-info text-center"> <h1 class="text-white">IG Downloader - 1.0.0</h1> <p class="text-white">Download unlimited images, videos by "user id" or "hashtag" from Instagram</p> </div> </div> </div> </div> </div> <div id="loading" style="display: none"> <h2 class="text-center">Downloading...</h2> <div class="cssload-thecube"> <div class="cssload-cube cssload-c1"></div> <div class="cssload-cube cssload-c2"></div> <div class="cssload-cube cssload-c4"></div> <div class="cssload-cube cssload-c3"></div> </div> </div> <div id="main-content" class="container"> <div class="row"> <div class="col-lg-12"> <br> <br> {% if succ_msg|length %} <div class="alert alert-primary text-center" role="alert"> {{succ_msg}} </div> {% endif %} {% if error_msg|length %} <div class="alert alert-danger text-center" role="alert" style="display: none;"> {{error_msg}} </div> {% endif %} </div> </div> </div> <h2></h2> <div style="margin-bottom: 10px"></div> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 < ! doctype html > < html lang = "en" > < head > < ! -- Required meta tags -- > < meta charset = "utf-8" > < meta name = "viewport" content = "width=device-width, initial-scale=1, shrink-to-fit=no" > < ! -- Bootstrap CSS -- > < link href = "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" type = "text/css" rel = "stylesheet" / > < link href = "{{ url_for('static', filename='css/style.css') }}" type = "text/css" rel = "stylesheet" / > <script type = "text/javascript" src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js" > </script> < title > IG Downloader < / title > <script> $ ( document ) . ready ( function ( ) { $ ( "#hashtag" ) . hide ( ) ; $ ( "#download_type" ) . change ( function ( ) { ( $ ( this ) . val ( ) == "by_user" ) ? $ ( "#user" ) . show ( ) : $ ( "#user" ) . hide ( ) ; ( $ ( this ) . val ( ) == "by_hashtag" ) ? $ ( "#hashtag" ) . show ( ) : $ ( "#hashtag" ) . hide ( ) ; } ) ; $ ( "#submit" ) . click ( function ( ) { var user_id_val = $ ( ".user" ) . val ( ) ; var hashtag_val = $ ( ".hashtag" ) . val ( ) ; if ( user_id_val . length || hashtag_val . length ) { $ ( "#loading" ) . css ( "display" , "block" ) ; $ ( "#main-content" ) . hide ( ) } $ ( ".alert-danger" ) . css ( "display" , "block" ) } ) ; } ) ; </script> < / head > < body > < div class = "gradient-overlay-half-primary-v1 bg-img-hero" "> <div class=" container space - 2 space - 4 - top -- lg space - 3 - bottom -- lg "> <div class=" row align - items - lg - center "> <div class=" col - lg - 7 "> <form method=" post " class=" "> <div class=" form - group "> <label class=" form - label text - white ">Select Download Type</label> <select id=" download _ type " name=" download _ type " class=" form - control "> <option value=" by _ user ">by User id</option> <option value=" by _ hashtag ">by Hashtag</option> </select> </div> <div class=" form - group " id=" user "> <label class=" form - label text - white ">Insert user id to download, for multi user downloads, put user ids separated by " , "</label> <input type=" text " name=" user " class=" form - control user " placeholder=" user1 , user2 , user3 "> </div> <div class=" form - group " id=" hashtag "> <label class=" form - label text - white ">Hashtag wihtout # ex: instagram</label> <input type=" text " name=" hashtag " class=" form - control hashtag " placeholder=" instagram "> </div> <div class=" form - group "> <label class=" form - label text - white ">Select Media Type</label> <select id=" media _ type " name=" media _ type " class=" form - control "> <option value=" ">All</option> <option value=" image ">Image</option> <option value=" video ">Video</option> </select> </div> <div class=" form - group "> <label class=" form - label text - white ">Select Download Items</label> <select id=" amount " name=" amount " class=" form - control "> <option value=" 10 ">10</option> <option value=" 20 ">20</option> <option value=" 50 ">50</option> <option value=" 100 ">100</option> <option value=" 200 ">200</option> <option value=" 300 ">300</option> <option value=" 500 ">500</option> <option value=" 1000 ">1000</option> <option value=" 1500 ">1500</option> <option value=" 2000 ">2000</option> <option value=" 3000 ">3000</option> <option value=" 4000 ">4000</option> <option value=" 5000 ">5000</option> </select> </div> <div class=" search_option _ button "> <button name=" submit " type=" submit " id=" submit " class=" btn btn - thm btn - secondary h70 ">Download</button> </div> </form> </div> <div class=" col - lg - 5 "> <div class=" product - info text - center "> <h1 class=" text - white ">IG Downloader - 1.0.0</h1> <p class=" text - white ">Download unlimited images, videos by " user id " or " hashtag " from Instagram</p> </div> </div> </div> </div> </div> <div id=" loading " style=" display : none "> <h2 class=" text - center ">Downloading...</h2> <div class=" cssload - thecube "> <div class=" cssload - cube cssload - c1 "></div> <div class=" cssload - cube cssload - c2 "></div> <div class=" cssload - cube cssload - c4 "></div> <div class=" cssload - cube cssload - c3 "></div> </div> </div> <div id=" main - content " class=" container "> <div class=" row "> <div class=" col - lg - 12 "> <br> <br> {% if succ_msg|length %} <div class=" alert alert - primary text - center " role=" alert "> {{succ_msg}} </div> {% endif %} {% if error_msg|length %} <div class=" alert alert - danger text - center " role=" alert " style=" display : none ; "> {{error_msg}} </div> {% endif %} </div> </div> </div> <h2></h2> <div style=" margin - bottom : 10px " > < / div > < / body > < / html >

Line 8, 9, 11 we loaded bootstrap, our template style and jquery. Line 16-39 we did some javascript code to interact with forms condition like if the user select download from user id then user field will be shown, and for hastag then hastag field will be shown. We will also show the loader when user clicked on submit button.

Line 49-97 we will get shown all required fields as user inputs. We will work with this fields data within our main file later on.

Line 124-141 the messages will be shown if instagram downloader worked successfully or not.

Step 2

Open style.css from css folder that is located inside templates folder. Put these below code

[class*="gradient-overlay-half"] { position: relative; z-index: 1; } .bg-img-hero { background-size: cover; background-repeat: no-repeat; background-position: top center; padding: 50px 0; } .gradient-overlay-half-primary-v1::before { background-image: linear-gradient(30deg, rgba(121, 110, 255, 0.95) 0%, rgba(33, 200, 122, 0.95) 100%); background-repeat: repeat-x; } [class*="gradient-overlay-half"]::before { position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: -1; width: 100%; height: 100%; content: ""; } /* Submit Button */ .home-job-search-box .search_option_button .btn { border: none; border-radius: 0 4px 4px 0; width: 140px; } .h70 { height: 50px; } .btn:not(:disabled):not(.disabled) { cursor: pointer; } .btn-thm { background-color: #82b440; color: #fff; font-size: 20px; font-weight: 700; padding: 7px 30px; -webkit-transition: all .3s ease; -o-transition: all .3s ease; transition: all .3s ease; } .dev-info a { color: #fff; text-decoration: underline; } .left_side { float: left; width: 275px; } /*--------------------------------------------------------------------- Loader -----------------------------------------------------------------------*/ .cssload-thecube { width: 73px; height: 73px; margin: 0 auto; margin-top: 49px; position: relative; transform: rotateZ(45deg); -o-transform: rotateZ(45deg); -ms-transform: rotateZ(45deg); -webkit-transform: rotateZ(45deg); -moz-transform: rotateZ(45deg); } .cssload-thecube .cssload-cube { position: relative; transform: rotateZ(45deg); -o-transform: rotateZ(45deg); -ms-transform: rotateZ(45deg); -webkit-transform: rotateZ(45deg); -moz-transform: rotateZ(45deg); } .cssload-thecube .cssload-cube { float: left; width: 50%; height: 50%; position: relative; transform: scale(1.1); -o-transform: scale(1.1); -ms-transform: scale(1.1); -webkit-transform: scale(1.1); -moz-transform: scale(1.1); } .cssload-thecube .cssload-cube:before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgb(43,160,199); animation: cssload-fold-thecube 2.76s infinite linear both; -o-animation: cssload-fold-thecube 2.76s infinite linear both; -ms-animation: cssload-fold-thecube 2.76s infinite linear both; -webkit-animation: cssload-fold-thecube 2.76s infinite linear both; -moz-animation: cssload-fold-thecube 2.76s infinite linear both; transform-origin: 100% 100%; -o-transform-origin: 100% 100%; -ms-transform-origin: 100% 100%; -webkit-transform-origin: 100% 100%; -moz-transform-origin: 100% 100%; } .cssload-thecube .cssload-c2 { transform: scale(1.1) rotateZ(90deg); -o-transform: scale(1.1) rotateZ(90deg); -ms-transform: scale(1.1) rotateZ(90deg); -webkit-transform: scale(1.1) rotateZ(90deg); -moz-transform: scale(1.1) rotateZ(90deg); } .cssload-thecube .cssload-c3 { transform: scale(1.1) rotateZ(180deg); -o-transform: scale(1.1) rotateZ(180deg); -ms-transform: scale(1.1) rotateZ(180deg); -webkit-transform: scale(1.1) rotateZ(180deg); -moz-transform: scale(1.1) rotateZ(180deg); } .cssload-thecube .cssload-c4 { transform: scale(1.1) rotateZ(270deg); -o-transform: scale(1.1) rotateZ(270deg); -ms-transform: scale(1.1) rotateZ(270deg); -webkit-transform: scale(1.1) rotateZ(270deg); -moz-transform: scale(1.1) rotateZ(270deg); } .cssload-thecube .cssload-c2:before { animation-delay: 0.35s; -o-animation-delay: 0.35s; -ms-animation-delay: 0.35s; -webkit-animation-delay: 0.35s; -moz-animation-delay: 0.35s; } .cssload-thecube .cssload-c3:before { animation-delay: 0.69s; -o-animation-delay: 0.69s; -ms-animation-delay: 0.69s; -webkit-animation-delay: 0.69s; -moz-animation-delay: 0.69s; } .cssload-thecube .cssload-c4:before { animation-delay: 1.04s; -o-animation-delay: 1.04s; -ms-animation-delay: 1.04s; -webkit-animation-delay: 1.04s; -moz-animation-delay: 1.04s; } @keyframes cssload-fold-thecube { 0%, 10% { transform: perspective(136px) rotateX(-180deg); opacity: 0; } 25%, 75% { transform: perspective(136px) rotateX(0deg); opacity: 1; } 90%, 100% { transform: perspective(136px) rotateY(180deg); opacity: 0; } } @-o-keyframes cssload-fold-thecube { 0%, 10% { -o-transform: perspective(136px) rotateX(-180deg); opacity: 0; } 25%, 75% { -o-transform: perspective(136px) rotateX(0deg); opacity: 1; } 90%, 100% { -o-transform: perspective(136px) rotateY(180deg); opacity: 0; } } @-ms-keyframes cssload-fold-thecube { 0%, 10% { -ms-transform: perspective(136px) rotateX(-180deg); opacity: 0; } 25%, 75% { -ms-transform: perspective(136px) rotateX(0deg); opacity: 1; } 90%, 100% { -ms-transform: perspective(136px) rotateY(180deg); opacity: 0; } } @-webkit-keyframes cssload-fold-thecube { 0%, 10% { -webkit-transform: perspective(136px) rotateX(-180deg); opacity: 0; } 25%, 75% { -webkit-transform: perspective(136px) rotateX(0deg); opacity: 1; } 90%, 100% { -webkit-transform: perspective(136px) rotateY(180deg); opacity: 0; } } @-moz-keyframes cssload-fold-thecube { 0%, 10% { -moz-transform: perspective(136px) rotateX(-180deg); opacity: 0; } 25%, 75% { -moz-transform: perspective(136px) rotateX(0deg); opacity: 1; } 90%, 100% { -moz-transform: perspective(136px) rotateY(180deg); opacity: 0; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 [class*="gradient-overlay-half"] { position : relative ; z-index : 1 ; } .bg-img-hero { background-size : cover ; background-repeat : no-repeat ; background-position : top center ; padding : 50px 0 ; } .gradient-overlay-half-primary-v1::before { background-image : linear-gradient ( 30deg, rgba ( 121, 110, 255, 0.95 ) 0%, rgba ( 33, 200, 122, 0.95 ) 100% ) ; background-repeat : repeat-x ; } [class*="gradient-overlay-half"]::before { position : absolute ; top : 0 ; right : 0 ; bottom : 0 ; left : 0 ; z-index : -1 ; width : 100% ; height : 100% ; content : "" ; } /* Submit Button */ .home-job-search-box .search_option_button .btn { border : none ; border-radius : 0 4px 4px 0 ; width : 140px ; } .h70 { height : 50px ; } .btn:not(:disabled):not(.disabled) { cursor : pointer ; } .btn-thm { background-color : #82b440 ; color : #fff ; font-size : 20px ; font-weight : 700 ; padding : 7px 30px ; -webkit-transition : all .3s ease ; -o-transition : all .3s ease ; transition : all .3s ease ; } .dev-info a { color : #fff ; text-decoration : underline ; } .left_side { float : left ; width : 275px ; } /*--------------------------------------------------------------------- Loader -----------------------------------------------------------------------*/ .cssload-thecube { width : 73px ; height : 73px ; margin : 0 auto ; margin-top : 49px ; position : relative ; transform : rotateZ ( 45deg ) ; -o-transform : rotateZ ( 45deg ) ; -ms-transform : rotateZ ( 45deg ) ; -webkit-transform : rotateZ ( 45deg ) ; -moz-transform : rotateZ ( 45deg ) ; } .cssload-thecube .cssload-cube { position : relative ; transform : rotateZ ( 45deg ) ; -o-transform : rotateZ ( 45deg ) ; -ms-transform : rotateZ ( 45deg ) ; -webkit-transform : rotateZ ( 45deg ) ; -moz-transform : rotateZ ( 45deg ) ; } .cssload-thecube .cssload-cube { float : left ; width : 50% ; height : 50% ; position : relative ; transform : scale ( 1.1 ) ; -o-transform : scale ( 1.1 ) ; -ms-transform : scale ( 1.1 ) ; -webkit-transform : scale ( 1.1 ) ; -moz-transform : scale ( 1.1 ) ; } .cssload-thecube .cssload-cube:before { content : "" ; position : absolute ; top : 0 ; left : 0 ; width : 100% ; height : 100% ; background-color : rgb ( 43,160,199 ) ; animation : cssload-fold-thecube 2.76s infinite linear both ; -o-animation : cssload-fold-thecube 2.76s infinite linear both ; -ms-animation : cssload-fold-thecube 2.76s infinite linear both ; -webkit-animation : cssload-fold-thecube 2.76s infinite linear both ; -moz-animation : cssload-fold-thecube 2.76s infinite linear both ; transform-origin : 100% 100% ; -o-transform-origin : 100% 100% ; -ms-transform-origin : 100% 100% ; -webkit-transform-origin : 100% 100% ; -moz-transform-origin : 100% 100% ; } .cssload-thecube .cssload-c2 { transform : scale ( 1.1 ) rotateZ ( 90deg ) ; -o-transform : scale ( 1.1 ) rotateZ ( 90deg ) ; -ms-transform : scale ( 1.1 ) rotateZ ( 90deg ) ; -webkit-transform : scale ( 1.1 ) rotateZ ( 90deg ) ; -moz-transform : scale ( 1.1 ) rotateZ ( 90deg ) ; } .cssload-thecube .cssload-c3 { transform : scale ( 1.1 ) rotateZ ( 180deg ) ; -o-transform : scale ( 1.1 ) rotateZ ( 180deg ) ; -ms-transform : scale ( 1.1 ) rotateZ ( 180deg ) ; -webkit-transform : scale ( 1.1 ) rotateZ ( 180deg ) ; -moz-transform : scale ( 1.1 ) rotateZ ( 180deg ) ; } .cssload-thecube .cssload-c4 { transform : scale ( 1.1 ) rotateZ ( 270deg ) ; -o-transform : scale ( 1.1 ) rotateZ ( 270deg ) ; -ms-transform : scale ( 1.1 ) rotateZ ( 270deg ) ; -webkit-transform : scale ( 1.1 ) rotateZ ( 270deg ) ; -moz-transform : scale ( 1.1 ) rotateZ ( 270deg ) ; } .cssload-thecube .cssload-c2:before { animation-delay : 0.35s ; -o-animation-delay : 0.35s ; -ms-animation-delay : 0.35s ; -webkit-animation-delay : 0.35s ; -moz-animation-delay : 0.35s ; } .cssload-thecube .cssload-c3:before { animation-delay : 0.69s ; -o-animation-delay : 0.69s ; -ms-animation-delay : 0.69s ; -webkit-animation-delay : 0.69s ; -moz-animation-delay : 0.69s ; } .cssload-thecube .cssload-c4:before { animation-delay : 1.04s ; -o-animation-delay : 1.04s ; -ms-animation-delay : 1.04s ; -webkit-animation-delay : 1.04s ; -moz-animation-delay : 1.04s ; } @keyframes cssload-fold-thecube { 0%, 10% { transform : perspective ( 136px ) rotateX ( -180deg ) ; opacity : 0 ; } 25%, 75% { transform : perspective ( 136px ) rotateX ( 0deg ) ; opacity : 1 ; } 90%, 100% { transform : perspective ( 136px ) rotateY ( 180deg ) ; opacity : 0 ; } } @-o-keyframes cssload-fold-thecube { 0%, 10% { -o-transform : perspective ( 136px ) rotateX ( -180deg ) ; opacity : 0 ; } 25%, 75% { -o-transform : perspective ( 136px ) rotateX ( 0deg ) ; opacity : 1 ; } 90%, 100% { -o-transform : perspective ( 136px ) rotateY ( 180deg ) ; opacity : 0 ; } } @-ms-keyframes cssload-fold-thecube { 0%, 10% { -ms-transform : perspective ( 136px ) rotateX ( -180deg ) ; opacity : 0 ; } 25%, 75% { -ms-transform : perspective ( 136px ) rotateX ( 0deg ) ; opacity : 1 ; } 90%, 100% { -ms-transform : perspective ( 136px ) rotateY ( 180deg ) ; opacity : 0 ; } } @-webkit-keyframes cssload-fold-thecube { 0%, 10% { -webkit-transform : perspective ( 136px ) rotateX ( -180deg ) ; opacity : 0 ; } 25%, 75% { -webkit-transform : perspective ( 136px ) rotateX ( 0deg ) ; opacity : 1 ; } 90%, 100% { -webkit-transform : perspective ( 136px ) rotateY ( 180deg ) ; opacity : 0 ; } } @-moz-keyframes cssload-fold-thecube { 0%, 10% { -moz-transform : perspective ( 136px ) rotateX ( -180deg ) ; opacity : 0 ; } 25%, 75% { -moz-transform : perspective ( 136px ) rotateX ( 0deg ) ; opacity : 1 ; } 90%, 100% { -moz-transform : perspective ( 136px ) rotateY ( 180deg ) ; opacity : 0 ; } }

Step 3

Open main file app.py and paste this code

from flask import Flask, render_template, request import webbrowser from threading import Timer import os app = Flask(__name__) @app.route('/', methods=['POST', 'GET']) def index(): try: download_type = request.form.getlist('download_type') download_type = download_type[0] user_id = request.form.get('user') hashtag = request.form.get('hashtag') download_id = '' if user_id: download_id = user_id if hashtag: download_id = ''+hashtag+' --tag' media_type = request.form.getlist('media_type') media_type = media_type[0] media_type_cmd = '' if media_type == 'image': media_type_cmd = '-t image' elif media_type == 'video': media_type_cmd = '-t video' else: media_type_cmd = '' amount = request.form.getlist('amount') amount = amount[0] amount_item = '-m '+amount+'' if user_id or hashtag: os.system("instagram-scraper "+download_id+" "+media_type_cmd+" "+amount_item+"") succ_msg = 'Download complete. Check this tool folder to get downloaded files' return render_template('index.html', succ_msg=succ_msg) return render_template('index.html') except: error_msg = 'Something went wrong, please check all inputs and try again' return render_template('index.html', error_msg=error_msg) def open_browser(): webbrowser.open_new('http://127.0.0.1:5000/') if __name__ == '__main__': Timer(1, open_browser).start(); app.run(port=5000) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 from flask import Flask , render_template , request import webbrowser from threading import Timer import os app = Flask ( __name__ ) @ app . route ( '/' , methods = [ 'POST' , 'GET' ] ) def index ( ) : try : download_type = request . form . getlist ( 'download_type' ) download_type = download_type [ 0 ] user_id = request . form . get ( 'user' ) hashtag = request . form . get ( 'hashtag' ) download_id = '' if user_id : download_id = user_id if hashtag : download_id = '' + hashtag + ' --tag' media_type = request . form . getlist ( 'media_type' ) media_type = media_type [ 0 ] media_type_cmd = '' if media_type == 'image' : media_type_cmd = '-t image' elif media_type == 'video' : media_type_cmd = '-t video' else : media_type_cmd = '' amount = request . form . getlist ( 'amount' ) amount = amount [ 0 ] amount_item = '-m ' + amount + '' if user_id or hashtag : os . system ( "instagram-scraper " + download_id + " " + media_type_cmd + " " + amount_item + "" ) succ_msg = 'Download complete. Check this tool folder to get downloaded files' return render_template ( 'index.html' , succ_msg = succ_msg ) return render_template ( 'index.html' ) except : error_msg = 'Something went wrong, please check all inputs and try again' return render_template ( 'index.html' , error_msg = error_msg ) def open_browser ( ) : webbrowser . open_new ( 'http://127.0.0.1:5000/' ) if __name__ == '__main__' : Timer ( 1 , open_browser ) . start ( ) ; app . run ( port = 5000 )

Line 1-4 we imported necessary dependencies. Line 10-49 made a function called index, where implemented our main login.

On line 53 you will see an another function open_browser. With this function when the tool get executed it will automatically open a web browser with the local server address http://127.0.0.1 and port 5000.

In case if your browser don’t open automatically after the run tool then you can manually open your browser and type the address http://127.0.0.1:5000 and this is the same.

Run this app

So we are successfully completed our instagram downloader script using Python and Flask. To run this app, right click on editor and click run or alternatively you can press Ctrl+Shift+F10

The final output should look like this

Please feel free to ask any question regarding this app on the comment section. I will try to answer you. Happy reading