downinst / app.py
jerrrycans's picture
Update app.py
0e2f7b8 verified
from flask import Flask, send_file, jsonify
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
import requests
import time
import io
import shutil
import os
import socket
app = Flask(__name__)
mobile_emulation = {
"deviceMetrics": {"width": 360, "height": 640, "pixelRatio": 3.0},
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36"
}
def get_instagram_ip():
try:
# Resolve instagram.com to IP using Python (which usually works better in containers)
ip = socket.gethostbyname("www.instagram.com")
print(f"DEBUG: Resolved www.instagram.com to {ip}")
return ip
except Exception as e:
print(f"DEBUG: DNS Resolution failed: {e}")
return None
def get_video_stream(target_url):
chrome_options = Options()
# 1. Resolve IP manually
ig_ip = get_instagram_ip()
if ig_ip:
# Force Chrome to map www.instagram.com to the resolved IP
# This bypasses Chrome's internal DNS resolver
chrome_options.add_argument(f'--host-resolver-rules=MAP www.instagram.com {ig_ip}, MAP .instagram.com {ig_ip}')
# 2. Standard Docker Flags
chrome_options.add_argument('--headless=new')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--disable-gpu')
# 3. Network Flags
chrome_options.add_argument('--dns-prefetch-disable')
chrome_options.add_argument('--disable-features=NetworkService')
# 4. User Data
user_data_dir = f'/tmp/chrome-user-data-{int(time.time())}'
chrome_options.add_argument(f'--user-data-dir={user_data_dir}')
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=chrome_options)
try:
print(f"Navigating to: {target_url}")
driver.get(target_url)
wait = WebDriverWait(driver, 20)
video_element = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "video")))
video_src = video_element.get_attribute('src')
print(f"Found Video SRC: {video_src}")
if not video_src:
raise Exception("No video src found")
# Use Python requests to download (it handles DNS better)
session = requests.Session()
headers = {
"User-Agent": mobile_emulation["userAgent"],
"Referer": "https://www.instagram.com/",
}
response = session.get(video_src, headers=headers, stream=True)
if response.status_code in [200, 206]:
return io.BytesIO(response.content)
else:
raise Exception(f"Download failed: {response.status_code}")
finally:
try:
driver.quit()
except:
pass
if os.path.exists(user_data_dir):
shutil.rmtree(user_data_dir, ignore_errors=True)
@app.route('/download/<path:link>')
def download_route(link):
if not link.startswith('http'):
link = f'https://{link}'
try:
print(f"Processing: {link}")
video_stream = get_video_stream(link)
return send_file(
video_stream,
mimetype='video/mp4',
as_attachment=True,
download_name=f'insta_{int(time.time())}.mp4'
)
except Exception as e:
print(f"ERROR: {e}")
return jsonify({"error": str(e), "logs": "Check logs"}), 500
@app.route('/')
def home():
return "Instagram Downloader (DNS Bypass Mode)"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860)