Mengunduh gambar melalui urllib dan python

184

Jadi saya mencoba membuat skrip Python yang mengunduh webcomics dan meletakkannya di folder di desktop saya. Saya telah menemukan beberapa program serupa di sini yang melakukan sesuatu yang serupa, tetapi tidak seperti yang saya butuhkan. Yang saya temukan paling mirip ada di sini ( http://bytes.com/topic/python/answers/850927-problem-using-urllib-download-images ). Saya mencoba menggunakan kode ini:

>>> import urllib
>>> image = urllib.URLopener()
>>> image.retrieve("http://www.gunnerkrigg.com//comics/00000001.jpg","00000001.jpg")
('00000001.jpg', <httplib.HTTPMessage instance at 0x1457a80>)

Saya kemudian mencari file "00000001.jpg" di komputer saya, tetapi yang saya temukan hanyalah gambar cache. Saya bahkan tidak yakin itu menyimpan file ke komputer saya. Setelah saya mengerti bagaimana cara mengunduh file, saya pikir saya tahu bagaimana menangani sisanya. Pada dasarnya cukup gunakan for loop dan pisahkan string pada '00000000'. 'Jpg' dan tambahkan '00000000' hingga jumlah terbesar, yang entah bagaimana harus saya tentukan. Adakah rekomendasi tentang cara terbaik untuk melakukan ini atau cara mengunduh file dengan benar?

Terima kasih!

EDIT 6/15/10

Ini adalah skrip yang sudah selesai, menyimpan file ke direktori yang Anda pilih. Untuk beberapa alasan aneh, file tidak diunduh dan mereka baru saja melakukannya. Setiap saran tentang cara membersihkannya akan sangat dihargai. Saat ini saya sedang mencari tahu bagaimana menemukan banyak komik di situs ini sehingga saya bisa mendapatkan yang terbaru, daripada membiarkan program berhenti setelah sejumlah pengecualian muncul.

import urllib
import os

comicCounter=len(os.listdir('/file'))+1  # reads the number of files in the folder to start downloading at the next comic
errorCount=0

def download_comic(url,comicName):
    """
    download a comic in the form of

    url = http://www.example.com
    comicName = '00000000.jpg'
    """
    image=urllib.URLopener()
    image.retrieve(url,comicName)  # download comicName at URL

while comicCounter <= 1000:  # not the most elegant solution
    os.chdir('/file')  # set where files download to
        try:
        if comicCounter < 10:  # needed to break into 10^n segments because comic names are a set of zeros followed by a number
            comicNumber=str('0000000'+str(comicCounter))  # string containing the eight digit comic number
            comicName=str(comicNumber+".jpg")  # string containing the file name
            url=str("http://www.gunnerkrigg.com//comics/"+comicName)  # creates the URL for the comic
            comicCounter+=1  # increments the comic counter to go to the next comic, must be before the download in case the download raises an exception
            download_comic(url,comicName)  # uses the function defined above to download the comic
            print url
        if 10 <= comicCounter < 100:
            comicNumber=str('000000'+str(comicCounter))
            comicName=str(comicNumber+".jpg")
            url=str("http://www.gunnerkrigg.com//comics/"+comicName)
            comicCounter+=1
            download_comic(url,comicName)
            print url
        if 100 <= comicCounter < 1000:
            comicNumber=str('00000'+str(comicCounter))
            comicName=str(comicNumber+".jpg")
            url=str("http://www.gunnerkrigg.com//comics/"+comicName)
            comicCounter+=1
            download_comic(url,comicName)
            print url
        else:  # quit the program if any number outside this range shows up
            quit
    except IOError:  # urllib raises an IOError for a 404 error, when the comic doesn't exist
        errorCount+=1  # add one to the error count
        if errorCount>3:  # if more than three errors occur during downloading, quit the program
            break
        else:
            print str("comic"+ ' ' + str(comicCounter) + ' ' + "does not exist")  # otherwise say that the certain comic number doesn't exist
print "all comics are up to date"  # prints if all comics are downloaded
Mike
sumber
Oke, saya punya semuanya untuk diunduh! Sekarang saya terjebak dengan solusi yang sangat tidak tepat untuk menentukan berapa banyak komik yang online ... Saya pada dasarnya menjalankan program ke nomor yang saya tahu melebihi jumlah komik dan kemudian menjalankan pengecualian untuk muncul ketika komik tidak ada, dan ketika pengecualian muncul lebih dari dua kali (karena saya tidak berpikir lebih dari dua komik akan hilang) itu keluar dari program, berpikir bahwa tidak ada lagi untuk diunduh. Karena saya tidak memiliki akses ke situs web, apakah ada cara terbaik untuk menentukan berapa banyak file yang ada di situs web? Saya akan memposting kode saya dalam sedetik.
Mike
creativebe.com/icombiner/merge-jpg.html Saya menggunakan program itu untuk menggabungkan semua file .jpg menjadi satu PDF. Bekerja luar biasa, dan gratis!
Mike
7
Pertimbangkan memposting solusi Anda sebagai jawaban, dan menghapusnya dari pertanyaan. Posting pertanyaan adalah untuk mengajukan pertanyaan, menjawab posting untuk jawaban :-)
BartoszKP
mengapa ini ditandai beautifulsoup? Posting ini muncul di daftar beautifulsouppertanyaan teratas
P0W
1
@ P0W Saya telah menghapus tag yang dibahas.
kmonsoor

Jawaban:

252

Python 2

Menggunakan urllib.urlretrieve

import urllib
urllib.urlretrieve("http://www.gunnerkrigg.com//comics/00000001.jpg", "00000001.jpg")

Python 3

Menggunakan urllib.request.urlretrieve (bagian dari antarmuka warisan Python 3, bekerja persis sama)

import urllib.request
urllib.request.urlretrieve("http://www.gunnerkrigg.com//comics/00000001.jpg", "00000001.jpg")
Matthew Flaschen
sumber
Tampaknya memotong ekstensi file untuk saya ketika diteruskan sebagai argumen (ekstensi ada di URL asli). Ada yang tahu kenapa?
JeffThompson
1
Ya, tentu saja. Saya pikir saya berasumsi bahwa jika tidak ada ekstensi file yang diberikan, ekstensi file akan ditambahkan. Itu masuk akal bagi saya pada saat itu, tetapi saya pikir sekarang saya mengerti apa yang terjadi.
JeffThompson
65
Catatan untuk Python 3 Anda perlu mengimpor [url.request] ( docs.python.org/3.0/library/… ):import urllib.request urllib.request.retrieve("http://...")
wasabigeek
1
Perhatikan bahwa daftar dokumen Python 3 mengambil () sebagai bagian dari "Legacy Interface" dan mengatakan itu mungkin akan usang di masa depan.
Nathan Wailes
18
Catatan untuk Python 3 sebenarnya import urllib.request urllib.request.urlretrieve("http://...jpg", "1.jpg"). Ini urlretrievesekarang seperti dari 3.x.
user1032613
81
import urllib
f = open('00000001.jpg','wb')
f.write(urllib.urlopen('http://www.gunnerkrigg.com//comics/00000001.jpg').read())
f.close()
DiGMi
sumber
70

Hanya sebagai catatan, menggunakan perpustakaan permintaan.

import requests
f = open('00000001.jpg','wb')
f.write(requests.get('http://www.gunnerkrigg.com//comics/00000001.jpg').content)
f.close()

Meskipun itu harus memeriksa kesalahan requests.get ().

ellimilial
sumber
1
Bahkan jika solusi ini tidak menggunakan urllib, Anda mungkin sudah menggunakan pustaka permintaan yang sudah ada dalam skrip python Anda (itu adalah kasus saya saat mencari ini) sehingga Anda mungkin ingin menggunakannya juga untuk mendapatkan gambar Anda.
Iam Zesh
Terima kasih telah mengirimkan jawaban ini di atas yang lain. Saya akhirnya membutuhkan tajuk ubahsuaian agar unduhan saya berfungsi, dan penunjuk ke pustaka permintaan mempersingkat proses agar semuanya berfungsi dengan baik bagi saya.
kuzzooroo
Bahkan tidak dapat membuat urllib berfungsi di python3. Permintaan tidak memiliki masalah dan sudah dimuat! Pilihan yang jauh lebih baik menurut saya.
user3023715
@ user3023715 di python3 Anda perlu mengimpor permintaan dari urllib lihat di sini
Yassine Sedrani
34

Untuk Python 3 Anda harus mengimpor import urllib.request:

import urllib.request 

urllib.request.urlretrieve(url, filename)

untuk info lebih lanjut lihat tautannya

HISI
sumber
15

Versi Python 3 dari jawaban @ DiGMi:

from urllib import request
f = open('00000001.jpg', 'wb')
f.write(request.urlopen("http://www.gunnerkrigg.com/comics/00000001.jpg").read())
f.close()
Dennis Golomazov
sumber
10

Saya telah menemukan jawaban ini dan saya mengeditnya dengan cara yang lebih dapat diandalkan

def download_photo(self, img_url, filename):
    try:
        image_on_web = urllib.urlopen(img_url)
        if image_on_web.headers.maintype == 'image':
            buf = image_on_web.read()
            path = os.getcwd() + DOWNLOADED_IMAGE_PATH
            file_path = "%s%s" % (path, filename)
            downloaded_image = file(file_path, "wb")
            downloaded_image.write(buf)
            downloaded_image.close()
            image_on_web.close()
        else:
            return False    
    except:
        return False
    return True

Dari sini Anda tidak pernah mendapatkan sumber atau pengecualian lain saat mengunduh.

Janith Chinthana
sumber
1
Anda harus menghapus 'diri'
Euphe
8

Jika Anda tahu bahwa file-file tersebut berada di direktori yang sama dirdengan situs web sitedan memiliki format berikut: filename_01.jpg, ..., filename_10.jpg lalu unduh semuanya:

import requests

for x in range(1, 10):
    str1 = 'filename_%2.2d.jpg' % (x)
    str2 = 'http://site/dir/filename_%2.2d.jpg' % (x)

    f = open(str1, 'wb')
    f.write(requests.get(str2).content)
    f.close()
len
sumber
7

Cara termudah adalah cukup .read()dengan membaca sebagian atau seluruh respons, lalu menuliskannya ke file yang telah Anda buka di lokasi yang dikenal baik.

Ignacio Vazquez-Abrams
sumber
5

Mungkin Anda membutuhkan 'User-Agent':

import urllib2
opener = urllib2.build_opener()
opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36')]
response = opener.open('http://google.com')
htmlData = response.read()
f = open('file.txt','w')
f.write(htmlData )
f.close()
Alexander
sumber
Mungkin halaman tidak tersedia?
Alexander
3

Selain menyarankan Anda membaca dokumen dengan retrieve()hati - hati ( http://docs.python.org/library/urllib.html#urllib.URLopener.retrieve ), saya akan menyarankan untuk benar-benar memanggil read()konten respons, dan kemudian menyimpannya ke dalam file pilihan Anda daripada meninggalkannya di file sementara yang mengambil buat.

Gabriel Hurley
sumber
3

Semua kode di atas, jangan izinkan untuk menyimpan nama gambar asli, yang kadang-kadang diperlukan. Ini akan membantu dalam menyimpan gambar ke drive lokal Anda, menjaga nama gambar asli

    IMAGE = URL.rsplit('/',1)[1]
    urllib.urlretrieve(URL, IMAGE)

Coba ini untuk lebih jelasnya.

Ojas
sumber
3

Ini bekerja untuk saya menggunakan python 3.

Ia mendapat daftar URL dari file csv dan mulai mengunduhnya ke dalam folder. Dalam hal konten atau gambar tidak ada, diperlukan pengecualian itu dan terus membuat keajaibannya.

import urllib.request
import csv
import os

errorCount=0

file_list = "/Users/$USER/Desktop/YOUR-FILE-TO-DOWNLOAD-IMAGES/image_{0}.jpg"

# CSV file must separate by commas
# urls.csv is set to your current working directory make sure your cd into or add the corresponding path
with open ('urls.csv') as images:
    images = csv.reader(images)
    img_count = 1
    print("Please Wait.. it will take some time")
    for image in images:
        try:
            urllib.request.urlretrieve(image[0],
            file_list.format(img_count))
            img_count += 1
        except IOError:
            errorCount+=1
            # Stop in case you reach 100 errors downloading images
            if errorCount>100:
                break
            else:
                print ("File does not exist")

print ("Done!")
Pemenang
sumber
2

Solusi yang lebih sederhana adalah (python 3):

import urllib.request
import os
os.chdir("D:\\comic") #your path
i=1;
s="00000000"
while i<1000:
    try:
        urllib.request.urlretrieve("http://www.gunnerkrigg.com//comics/"+ s[:8-len(str(i))]+ str(i)+".jpg",str(i)+".jpg")
    except:
        print("not possible" + str(i))
    i+=1;
Ayush
sumber
Hati-hati menggunakan bare kecuali seperti itu, lihat stackoverflow.com/questions/54948548/… .
AMC
1

Bagaimana dengan ini:

import urllib, os

def from_url( url, filename = None ):
    '''Store the url content to filename'''
    if not filename:
        filename = os.path.basename( os.path.realpath(url) )

    req = urllib.request.Request( url )
    try:
        response = urllib.request.urlopen( req )
    except urllib.error.URLError as e:
        if hasattr( e, 'reason' ):
            print( 'Fail in reaching the server -> ', e.reason )
            return False
        elif hasattr( e, 'code' ):
            print( 'The server couldn\'t fulfill the request -> ', e.code )
            return False
    else:
        with open( filename, 'wb' ) as fo:
            fo.write( response.read() )
            print( 'Url saved as %s' % filename )
        return True

##

def main():
    test_url = 'http://cdn.sstatic.net/stackoverflow/img/favicon.ico'

    from_url( test_url )

if __name__ == '__main__':
    main()
Gmas80
sumber
0

Jika Anda memerlukan dukungan proxy, Anda dapat melakukan ini:

  if needProxy == False:
    returnCode, urlReturnResponse = urllib.urlretrieve( myUrl, fullJpegPathAndName )
  else:
    proxy_support = urllib2.ProxyHandler({"https":myHttpProxyAddress})
    opener = urllib2.build_opener(proxy_support)
    urllib2.install_opener(opener)
    urlReader = urllib2.urlopen( myUrl ).read() 
    with open( fullJpegPathAndName, "w" ) as f:
      f.write( urlReader )
Eamonn Kenny
sumber
0

Cara lain untuk melakukan ini adalah melalui perpustakaan fastai. Ini bekerja seperti pesona bagi saya. Saya menghadapi SSL: CERTIFICATE_VERIFY_FAILED Errorpenggunaan urlretrievejadi saya mencobanya.

url = 'https://www.linkdoesntexist.com/lennon.jpg'
fastai.core.download_url(url,'image1.jpg', show_progress=False)
Sid
sumber
Saya menghadapi SSL: CERTIFICATE_VERIFY_FAILED Kesalahan stackoverflow.com/questions/27835619/…
AMC
0

Menggunakan permintaan

import requests
import shutil,os

headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
currentDir = os.getcwd()
path = os.path.join(currentDir,'Images')#saving images to Images folder

def ImageDl(url):
    attempts = 0
    while attempts < 5:#retry 5 times
        try:
            filename = url.split('/')[-1]
            r = requests.get(url,headers=headers,stream=True,timeout=5)
            if r.status_code == 200:
                with open(os.path.join(path,filename),'wb') as f:
                    r.raw.decode_content = True
                    shutil.copyfileobj(r.raw,f)
            print(filename)
            break
        except Exception as e:
            attempts+=1
            print(e)

if __name__ == '__main__':
    ImageDl(url)
Sohan Das
sumber
0

Dengan menggunakan urllib, Anda bisa menyelesaikan ini secara instan.

import urllib.request

opener=urllib.request.build_opener()
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
urllib.request.install_opener(opener)

urllib.request.urlretrieve(URL, "images/0.jpg")
Sreekant Shenoy
sumber