Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

ดาวน์โหลดไฟล์จากเว็บด้วย Python

Python มีโมดูลหลายตัว เช่น urllib, requests สำหรับดาวน์โหลดไฟล์จากเว็บ บทความนี้จะใช้ไลบรารี requests ซึ่งมีประสิทธิภาพและใช้งานง่าย

ขั้นตอนการดาวน์โหลดไฟล์ด้วย requests

1. นำเข้าโมดูล

import requests

2. ระบุ URL และดึงข้อมูล

url = 'https://www.facebook.com/favicon.ico'
r = requests.get(url, allow_redirects=True)

3. บันทึกไฟล์

open('facebook.ico', 'wb').write(r.content)

ไฟล์จะถูกบันทึกเป็น facebook.ico ในโฟลเดอร์ทำงานปัจจุบัน

ตัวอย่างโค้ดสมบูรณ์

import requests
url = 'https://www.facebook.com/favicon.ico'
r = requests.get(url, allow_redirects=True)
open('facebook.ico', 'wb').write(r.content)

ตรวจสอบประเภทไฟล์ก่อนดาวน์โหลด

สามารถตรวจสอบ Content-Type จาก Header ได้:

>> r = requests.get(url, allow_redirects=True)
>>> print(r.headers.get('content-type'))
image/png

วิธีที่ฉลาดกว่าคือใช้ HEAD request เพื่อดู Header เท่านั้น ไม่ต้องดาวน์โหลดเนื้อหา:

def is_downloadable(url):
    h = requests.head(url, allow_redirects=True)
    content_type = h.headers.get('content-type', '')
    return 'text' not in content_type and 'html' not in content_type

print(is_downloadable('https://www.youtube.com/watch?v=xCglV_dqFGI'))  # False
print(is_downloadable('https://www.facebook.com/favicon.ico'))        # True

จำกัดขนาดไฟล์

ตรวจสอบ Content-Length ก่อนดาวน์โหลด:

content_length = h.headers.get('content-length')
if content_length and int(content_length) > 2e8:  # 200 MB
    return False

ดึงชื่อไฟล์จาก URL

วิธีง่าย: ตัดจากส่วนท้ายของ URL

url = "https://www.example.com/wp-content/uploads/2016/05/logo.png"
if '/' in url:
    filename = url.rsplit('/', 1)[1]
    print(filename)  # logo.png

กรณี URL ไม่มีชื่อไฟล์ (เช่น https://url.com/download) ให้ใช้ Header Content-Disposition:

import requests
import re

def get_filename_from_cd(cd):
    """ดึงชื่อไฟล์จาก Content-Disposition header"""
    if not cd:
        return None
    fname = re.findall('filename=(.+)', cd)
    return fname[0] if fname else None

url = 'https://google.com/favicon.ico'
r = requests.get(url, allow_redirects=True)
filename = get_filename_from_cd(r.headers.get('content-disposition'))
if filename:
    open(filename, 'wb').write(r.content)

รวมวิธีทั้งสองจะได้ชื่อไฟล์ที่ถูกต้องในส่วนใหญ่

Python มีโมดูลหลายตัว เช่น urllib, requests สำหรับดาวน์โหลดไฟล์จากเว็บ บทความนี้จะใช้ไลบรารี requests ซึ่งมีประสิทธิภาพและใช้งานง่าย

ขั้นตอนการดาวน์โหลดไฟล์ด้วย requests

1. นำเข้าโมดูล

import requests

2. ระบุ URL และดึงข้อมูล

url = 'https://www.facebook.com/favicon.ico'
r = requests.get(url, allow_redirects=True)

3. บันทึกไฟล์

open('facebook.ico', 'wb').write(r.content)

ไฟล์จะถูกบันทึกเป็น facebook.ico ในโฟลเดอร์ทำงานปัจจุบัน

ตัวอย่างโค้ดสมบูรณ์

import requests
url = 'https://www.facebook.com/favicon.ico'
r = requests.get(url, allow_redirects=True)
open('facebook.ico', 'wb').write(r.content)

ตรวจสอบประเภทไฟล์ก่อนดาวน์โหลด

สามารถตรวจสอบ Content-Type จาก Header ได้:

>> r = requests.get(url, allow_redirects=True)
>>> print(r.headers.get('content-type'))
image/png

วิธีที่ฉลาดกว่าคือใช้ HEAD request เพื่อดู Header เท่านั้น ไม่ต้องดาวน์โหลดเนื้อหา:

def is_downloadable(url):
    h = requests.head(url, allow_redirects=True)
    content_type = h.headers.get('content-type', '')
    return 'text' not in content_type and 'html' not in content_type

print(is_downloadable('https://www.youtube.com/watch?v=xCglV_dqFGI'))  # False
print(is_downloadable('https://www.facebook.com/favicon.ico'))        # True

จำกัดขนาดไฟล์

ตรวจสอบ Content-Length ก่อนดาวน์โหลด:

content_length = h.headers.get('content-length')
if content_length and int(content_length) > 2e8:  # 200 MB
    return False

ดึงชื่อไฟล์จาก URL

วิธีง่าย: ตัดจากส่วนท้ายของ URL

url = "https://www.example.com/wp-content/uploads/2016/05/logo.png"
if '/' in url:
    filename = url.rsplit('/', 1)[1]
    print(filename)  # logo.png

กรณี URL ไม่มีชื่อไฟล์ (เช่น https://url.com/download) ให้ใช้ Header Content-Disposition:

import requests
import re

def get_filename_from_cd(cd):
    """ดึงชื่อไฟล์จาก Content-Disposition header"""
    if not cd:
        return None
    fname = re.findall('filename=(.+)', cd)
    return fname[0] if fname else None

url = 'https://google.com/favicon.ico'
r = requests.get(url, allow_redirects=True)
filename = get_filename_from_cd(r.headers.get('content-disposition'))
if filename:
    open(filename, 'wb').write(r.content)

รวมวิธีทั้งสองจะได้ชื่อไฟล์ที่ถูกต้องในส่วนใหญ่