การดาวน์โหลดไฟล์ http พื้นฐานและการบันทึกลงดิสก์ในไพ ธ อน?


159

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

มีคนช่วยอธิบายวิธีแก้ปัญหาง่ายๆให้กับ 'การดาวน์โหลดไฟล์ผ่าน http' และ 'การบันทึกลงดิสก์ใน Windows' ให้ฉันได้ไหม

ฉันไม่แน่ใจว่าจะใช้โมดูล shutil และ os ได้อย่างไร

ไฟล์ที่ฉันต้องการดาวน์โหลดมีขนาดไม่เกิน 500 MB และเป็นไฟล์เก็บถาวร. gz หากใครบางคนสามารถอธิบายวิธีแยกไฟล์เก็บถาวรและใช้ไฟล์ในนั้นได้นั่นก็จะดีมาก!

นี่เป็นวิธีแก้ปัญหาบางส่วนที่ฉันเขียนจากคำตอบต่าง ๆ รวมกัน:

import requests
import os
import shutil

global dump

def download_file():
    global dump
    url = "http://randomsite.com/file.gz"
    file = requests.get(url, stream=True)
    dump = file.raw

def save_file():
    global dump
    location = os.path.abspath("D:\folder\file.gz")
    with open("file.gz", 'wb') as location:
        shutil.copyfileobj(dump, location)
    del dump

ใครช่วยชี้ให้เห็นข้อผิดพลาด (ระดับเริ่มต้น) และอธิบายวิธีการที่ง่ายขึ้นในการทำเช่นนี้?

ขอบคุณ!

คำตอบ:


207

วิธีที่สะอาดในการดาวน์โหลดไฟล์คือ:

import urllib

testfile = urllib.URLopener()
testfile.retrieve("http://randomsite.com/file.gz", "file.gz")

file.gzนี้จะดาวน์โหลดไฟล์จากเว็บไซต์และชื่อมัน นี้เป็นหนึ่งในโซลูชั่นที่ชื่นชอบจากการดาวน์โหลดภาพผ่าน urllib และงูหลาม

ตัวอย่างนี้ใช้urllibไลบรารีและมันจะดึงไฟล์จากแหล่งที่มาโดยตรง


3
โอเคขอบคุณ! แต่มีวิธีที่จะทำให้มันทำงานผ่านการร้องขอได้หรือไม่?
arvindch

5
มีความเป็นไปได้ที่จะบันทึกใน /myfolder/file.gz หรือไม่
John Snow

17
ไม่มีความเป็นไปได้ที่ดีไปกว่าการลองด้วยตัวเองใช่ไหม :) testfile.retrieve("http://example.com/example.rpm", "/tmp/test.rpm")ฉันประสบความสำเร็จสามารถทำ
Dharmit

18
สิ่งนี้เลิกใช้แล้วตั้งแต่ Python 3.3 และวิธีแก้ปัญหา urllib.request.urlretrieve (ดูคำตอบด้านล่าง) เป็นวิธี 'ทันสมัย'
MichielB

1
วิธีที่ดีที่สุดในการเพิ่มชื่อผู้ใช้และรหัสผ่านในรหัสนี้คืออะไร tks
Estefy

110

ดังที่กล่าวไว้ที่นี่ :

import urllib
urllib.urlretrieve ("http://randomsite.com/file.gz", "file.gz")

EDIT:หากคุณยังคงต้องการที่จะร้องขอการใช้งานดูที่คำถามนี้หรืออย่างใดอย่างหนึ่ง


1
อย่างไรก็ตาม urllib จะทำงานได้ แต่หลาย ๆ คนดูเหมือนจะแนะนำให้ใช้คำขอมากกว่า urllib ทำไมเป็นอย่างนั้น?
arvindch

2
requestsมีประโยชน์มากเมื่อเทียบกับurllibเมื่อทำงานกับ REST API เว้นแต่คุณกำลังมองหาที่จะทำมากขึ้นนี้ควรจะดี
dparpyani

ตกลงตอนนี้ฉันได้อ่านลิงก์ที่คุณให้ไว้สำหรับคำขอการใช้งานแล้ว ฉันสับสนเกี่ยวกับวิธีประกาศเส้นทางไฟล์เพื่อบันทึกการดาวน์โหลด ฉันจะใช้ระบบปฏิบัติการและปิดเครื่องได้อย่างไร
arvindch

62
สำหรับ Python3:import urllib.request urllib.request.urlretrieve(url, filename)
แฟลช

1
ฉันไม่สามารถดึงรหัสสถานะ http ได้ด้วยวิธีนี้หากการดาวน์โหลดล้มเหลว
Aashish Thite

34

ฉันใช้wget

ห้องสมุดที่เรียบง่ายและดีถ้าคุณต้องการที่จะเป็นตัวอย่าง?

import wget

file_url = 'http://johndoe.com/download.zip'

file_name = wget.download(file_url)

โมดูล wget รองรับ python 2 และ python 3 เวอร์ชั่น


33

สี่วิธีใช้ wget, urllib และการร้องขอ

#!/usr/bin/python
import requests
from StringIO import StringIO
from PIL import Image
import profile as profile
import urllib
import wget


url = 'https://tinypng.com/images/social/website.jpg'

def testRequest():
    image_name = 'test1.jpg'
    r = requests.get(url, stream=True)
    with open(image_name, 'wb') as f:
        for chunk in r.iter_content():
            f.write(chunk)

def testRequest2():
    image_name = 'test2.jpg'
    r = requests.get(url)
    i = Image.open(StringIO(r.content))
    i.save(image_name)

def testUrllib():
    image_name = 'test3.jpg'
    testfile = urllib.URLopener()
    testfile.retrieve(url, image_name)

def testwget():
    image_name = 'test4.jpg'
    wget.download(url, image_name)

if __name__ == '__main__':
    profile.run('testRequest()')
    profile.run('testRequest2()')
    profile.run('testUrllib()')
    profile.run('testwget()')

testRequest - การเรียกใช้ฟังก์ชัน 4469882 (การโทรดั้งเดิม 4469842) ใน 20.236 วินาที

testRequest2 - การเรียกใช้ฟังก์ชัน 8580 (การโทรดั้งเดิม 8574) ใน 0.072 วินาที

testUrllib - การเรียกใช้ฟังก์ชัน 3810 (การโทรดั้งเดิม 3775 ครั้ง) ใน 0.036 วินาที

testwget - 3489 ฟังก์ชั่นการโทรใน 0.020 วินาที


1
คุณเรียกจำนวนฟังก์ชั่นได้อย่างไร?
Abdelhak

29

สำหรับPython3 + URLopenerเลิกใช้แล้ว และเมื่อใช้แล้วคุณจะได้รับข้อผิดพลาดดังนี้:

url_opener = urllib.URLopener () AttributeError: โมดูล 'urllib' ไม่มีแอตทริบิวต์ 'URLopener'

ดังนั้นลอง:

import urllib.request 
urllib.request.urlretrieve(url, filename)

1
แปลก ... ทำไมไม่มีใครโหวตให้กับคำตอบนี้เมื่อ Python 2 เลิกใช้แล้วและวิธีแก้ปัญหานี้ควรจะทำงานได้อย่างถูกต้อง ...
wowkin2

1
ตกลงกัน! ฉันดึงเส้นผมของฉันไปที่ทางออกก่อนหน้านี้ หวังว่าฉันจะสามารถโหวตได้ 200 ครั้ง!
Yechiel K


1

ฉันเริ่มต้นเส้นทางนี้เนื่องจาก wget ของ ESXi ไม่ได้รวบรวมกับ SSL และฉันต้องการดาวน์โหลด OVA จากเว็บไซต์ของผู้จำหน่ายโดยตรงไปยังโฮสต์ ESXi ซึ่งอยู่อีกด้านหนึ่งของโลก

ฉันต้องปิดการใช้งานไฟร์วอลล์ (ขี้เกียจ) / เปิดใช้งาน https out โดยแก้ไขกฎ (เหมาะสม)

สร้างสคริปต์หลาม:

import ssl
import shutil
import tempfile
import urllib.request
context = ssl._create_unverified_context()

dlurl='https://somesite/path/whatever'
with urllib.request.urlopen(durl, context=context) as response:
    with open("file.ova", 'wb') as tmp_file:
        shutil.copyfileobj(response, tmp_file)

ไลบรารี ESXi นั้นถูกจับคู่ แต่ตัวติดตั้งพังพอนโอเพนซอร์สดูเหมือนจะใช้ urllib สำหรับ https ... ดังนั้นมันจึงเป็นแรงบันดาลใจให้ฉันลงเส้นทางนี้


-5

อีกวิธีที่สะอาดในการบันทึกไฟล์คือ:

import csv
import urllib

urllib.retrieve("your url goes here" , "output.csv")

นี่อาจจะเป็นurllib.urlretrieveหรือurllib.URLopener().retrieveไม่ชัดเจนซึ่งคุณหมายถึงที่นี่
ร่วมงาน

9
ทำไมคุณนำเข้า csv หากคุณเพิ่งตั้งชื่อไฟล์
Azeezah M
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.