Urllib ve python ile resim indirme


184

Bu yüzden webcomics'i indirip masaüstümdeki bir klasöre koyan bir Python betiği yapmaya çalışıyorum. Burada benzer bir şey yapan birkaç benzer program buldum, ama ihtiyacım olan şey gibi değil. En çok benzediğim şey tam burada ( http://bytes.com/topic/python/answers/850927-problem-using-urllib-download-images ). Bu kodu kullanmayı denedim:

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

Daha sonra bilgisayarımda "00000001.jpg" dosyasını aradım, ancak bulduğum tek şey önbelleğe alınmış resimdi. Dosyayı bilgisayarıma kaydettiğinden bile emin değilim. Dosyayı nasıl indireceğimi anladıktan sonra, geri kalanının nasıl ele alınacağını biliyorum. Temelde sadece bir for döngüsü kullanın ve '00000000' .jpg'de dizeyi bölün ve '00000000' değerini bir şekilde belirlemem gereken en büyük sayıya kadar artırın. Herhangi bir öneri bunu yapmak için nasıl veya doğru dosyayı indirmek için nasıl?

Teşekkürler!

EDIT 6/15/10

İşte tamamlanmış komut dosyası, dosyaları seçtiğiniz herhangi bir dizine kaydeder. Bazı tuhaf nedenlerden dolayı dosyalar indirilmiyordu ve sadece yaptılar. Nasıl temizlemek için herhangi bir öneri çok takdir edilecektir. Şu anda sitede çok sayıda çizgi roman bulmak için nasıl çalışıyorum, bu yüzden belirli bir sayıda istisna ortaya çıkarıldıktan sonra programdan çıkmak yerine, sadece en son bir tane alabilirim.

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

Tamam, hepsini indirdim! Şimdi kaç çizgi romanın çevrimiçi olduğunu belirlemek için çok beceriksiz bir çözümle sıkıştım ... Temelde programı çizgi roman sayısının üzerinde olduğunu bildiğim bir sayıya çalıştırıyorum ve sonra bir çizgi roman gelmediğinde bir istisna çalıştırıyorum mevcut değil ve istisna iki kereden fazla ortaya çıktığında (ikiden fazla çizgi romanın eksik olacağını düşünmediğimden) indirilecek daha fazla şey olmadığını düşünerek programdan çıkıyor. Web sitesine erişimim olmadığından, web sitesinde kaç dosya olduğunu belirlemenin en iyi yolu var mı? Kodumu bir saniye içinde yayınlayacağım.
Mike

creativebe.com/icombiner/merge-jpg.html Bu programı, tüm .jpg dosyalarını tek bir PDF'de birleştirmek için kullandım. Harika çalışıyor ve ücretsiz!
Mike

7
Çözümünüzü bir cevap olarak yayınlamayı ve sorudan çıkarmayı düşünün. Soru mesajları soru sormak için, cevapları cevap mesajları :-)
BartoszKP

bu neden etiketlendi beautifulsoup? Bu yazı en çok beautifulsoupsorulan sorular listesinde görünüyor
P0W

1
@ P0W Tartışılan etiketi kaldırdım.
kmonsoor

Yanıtlar:


252

Python 2

Urllib.urlretrieve kullanma

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

Python 3

Kullanılması urllib.request.urlretrieve (Python 3'ün mirası arabiriminin parçası, tam olarak aynı çalışır)

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

Bir argüman olarak iletildiğinde dosya uzantısını kesiyor gibi görünüyor (uzantı orijinal URL'de mevcut). Neden olduğu hakkında bir fikrin var mı?
JeffThompson

1
Sevgiler, evet. Sanırım hiçbir dosya uzantısı verilmemişse, dosyanın uzantısının ekleneceğini varsaydım. O zaman bana mantıklı geldi, ama sanırım şimdi neler olduğunu anlıyorum.
JeffThompson

65
Python 3 için [url.request] dosyasını içe aktarmanız gerekir ( docs.python.org/3.0/library/… ):import urllib.request urllib.request.retrieve("http://...")
wasabigeek

1
Not olduğunu Python 3 dokümanlar listesi "Eski Arayüz" kapsamında () almak ve gelecekte kullanım dışı hale gelebilir söylüyorlar.
Nathan Wailes

18
Python 3 için aslında not import urllib.request urllib.request.urlretrieve("http://...jpg", "1.jpg"). Bu var urlretrieve3.x şimdi
user1032613 16:18

81
import urllib
f = open('00000001.jpg','wb')
f.write(urllib.urlopen('http://www.gunnerkrigg.com//comics/00000001.jpg').read())
f.close()

70

Sadece kayıt için, istek kütüphanesini kullanarak.

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

Yine de requests.get () hatasını kontrol etmelidir.


1
Bu çözüm urllib kullanmıyor olsa bile, zaten python betiğinizde (bu arama yaparken benim durumum) istek kitaplığını zaten kullanıyor olabilirsiniz, böylece resimlerinizi almak için de kullanmak isteyebilirsiniz.
Iam Zesh

Bu yanıtı diğerlerinin üzerine gönderdiğiniz için teşekkür ederiz. İndirme işlemimin çalışmasını sağlamak için özel başlıklara ihtiyacım vardı ve istek kitaplığına işaretçi, her şeyin benim için çalışmasını önemli ölçüde kısalttı.
kuzzooroo

Urllib'in python3'te çalışmasını bile sağlayamadım. İsteklerde sorun yoktu ve zaten yüklenmiş! Bence çok daha iyi bir seçim.
user3023715

@ user3023715 in python3 urllib'den istek almanız gerekiyor buraya bakın
Yassine Sedrani

34

Python 3 için şunları içe aktarmanız gerekir import urllib.request:

import urllib.request 

urllib.request.urlretrieve(url, filename)

daha fazla bilgi için bağlantıya göz atın


15

@ DiGMi'nin cevabının Python 3 sürümü:

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

10

Bu cevabı buldum ve bunu daha güvenilir bir şekilde düzenliyorum

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

Bundan indirirken asla başka kaynak veya istisna alamazsınız.


1
'Kendini' kaldırmalısın
Euphe

8

Dosyaların dirweb sitesinin aynı dizininde sitebulunduğunu ve aşağıdaki biçime sahip olduğunu biliyorsanız : dosyaadı_01.jpg, ..., dosyaadı_10.jpg hepsini indirin:

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()

7

.read()Kısmi veya tüm yanıtı okumak ve daha sonra bilinen iyi bir konumda açtığınız bir dosyaya yazmak en kolay yoldur .


5

Belki de 'User-Agent'a ihtiyacınız var:

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()

Belki sayfa mevcut değil?
Alexander


3

Yukarıdaki tüm kodlar, bazen gerekli olan orijinal görüntü adının korunmasına izin vermez. Bu, orijinal görüntü adını koruyarak görüntüleri yerel sürücünüze kaydetmenize yardımcı olacaktır.

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

Daha fazla ayrıntı için bunu deneyin .


3

Bu benim için python 3 kullanarak çalıştı.

Csv dosyasından bir URL listesi alır ve bunları bir klasöre indirmeye başlar. İçerik veya resim yoksa, bu istisnayı alır ve sihrini yapmaya devam eder.

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!")

2

Daha basit bir çözüm olabilir (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;

Bunun dışında bir çıplak kullanma konusunda dikkatli olun, bkz. Stackoverflow.com/questions/54948548/… .
AMC

1

Peki buna ne dersin:

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()

0

Proxy desteğine ihtiyacınız varsa bunu yapabilirsiniz:

  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 )

0

Bunu yapmanın bir başka yolu da fastai kütüphanesi. Bu benim için bir cazibe gibi çalıştı. Ben bakıyordu SSL: CERTIFICATE_VERIFY_FAILED Errorkullanarak urlretrieveBunu denedim böylece.

url = 'https://www.linkdoesntexist.com/lennon.jpg'
fastai.core.download_url(url,'image1.jpg', show_progress=False)

Bir SSL ile karşılaştım: CERTIFICATE_VERIFY_FAILED Hata stackoverflow.com/questions/27835619/…
AMC

0

İstekleri kullanma

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)

0

Urllib'i kullanarak bunu anında yapabilirsiniz.

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")
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.