import os
import shutil
from urllib.request import ProxyHandler, build_opener

proxy = 'http://proxy.example.net:8080'
opener = build_opener(ProxyHandler({
    'http': proxy,
    'https': proxy,
}))

temporary = 'archive.zip.part'
destination = 'archive.zip'

with opener.open('https://downloads.example.net/archive.zip',
                 timeout=20) as response:
    with open(temporary, 'wb') as output:
        shutil.copyfileobj(response, output)

os.replace(temporary, destination)

แทนที่ URL และชื่อไฟล์สำหรับแอปพลิเคชัน สำหรับการดาวน์โหลดไฟล์สาธารณะที่ได้รับอนุญาตโดยไม่มีการพิสูจน์ตัวตนพร็อกซี รายการพร็อกซี HTTP สามารถให้ปลายทางที่เป็นไปได้สำหรับ URL ของพร็อกซี ตัวเปิด urllib เฉพาะนี้ใช้พร็อกซี HTTP สำหรับปลายทาง HTTPS พร้อมการตรวจสอบใบรับรองตามปกติ ไม่ได้ติดตั้งตัวเปิดระดับโลก การพิสูจน์ตัวตนหากจำเป็นต้องใช้การตั้งค่าที่รองรับ

copyfileobj คัดลอกเป็นชิ้น การออกจากบริบทไฟล์จะปิดไฟล์และล้างการเขียนที่บัฟเฟอร์ไว้ก่อนที่ os.replace จะติดตั้งชื่อสุดท้าย

หากคำขอหรือการคัดลอกทำให้เกิดข้อผิดพลาด การเปลี่ยนชื่อจะถูกข้าม ไฟล์บางส่วนอาจเหลืออยู่ตามนโยบายการล้างข้อมูล และลำดับนี้จะไม่แตะต้องไฟล์สุดท้ายที่มีอยู่เมื่อเกิดความล้มเหลวนั้น หากสำเร็จ การแทนที่จะเขียนทับไฟล์สุดท้ายนั้นได้ ดังนั้นจงเลือกนโยบายอย่างตั้งใจ

ใช้ชื่อชั่วคราวที่ไม่ซ้ำกันสำหรับงานที่ทำพร้อมกัน วัตถุตัวเปิดที่แยกจากกันไม่ปกป้องงานที่ใช้เส้นทาง .part เดียวกัน

การตั้งค่า 20 วินาทีจำกัดการทำงานของซ็อกเก็ตที่รองรับ ไม่ใช่เวลาดาวน์โหลดทั้งหมด กำหนดเวลาสำหรับงานทั้งหมดต้องจัดการแยกในแอปพลิเคชัน การถ่ายโอนเสร็จสิ้นก็แยกจากการตรวจสอบไฟล์ที่ดาวน์โหลด

บทความที่เกี่ยวข้อง