การดาวน์โหลดรูปภาพผ่าน urllib และ python


183

ดังนั้นฉันจึงพยายามสร้างสคริปต์ Python ที่ดาวน์โหลดคอมมิคส์และวางไว้ในโฟลเดอร์บนเดสก์ท็อปของฉัน ฉันพบโปรแกรมที่คล้ายกันสองสามรายการที่นี่ซึ่งทำสิ่งที่คล้ายกัน แต่ไม่มีอะไรที่เหมือนกับสิ่งที่ฉันต้องการ สิ่งที่ฉันคิดว่าคล้ายกันมากที่สุดอยู่ที่นี่ ( http://bytes.com/topic/python/answers/850927-problem-using-urllib-download-images ) ฉันพยายามใช้รหัสนี้:

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

จากนั้นฉันค้นหาคอมพิวเตอร์ของฉันเพื่อหาไฟล์ "00000001.jpg" แต่สิ่งที่ฉันพบคือรูปภาพแคชของมัน ฉันไม่แน่ใจด้วยซ้ำว่าบันทึกไฟล์ไว้ในคอมพิวเตอร์ของฉัน เมื่อฉันเข้าใจวิธีดาวน์โหลดไฟล์ฉันคิดว่าฉันรู้วิธีจัดการกับส่วนที่เหลือ เป็นหลักเพียงใช้สำหรับวนรอบและแยกสตริงที่ '00000000'. 'jpg' และเพิ่ม '00000000' เป็นจำนวนมากที่สุดซึ่งฉันจะต้องพิจารณาอย่างใด คำแนะนำใด ๆ เกี่ยวกับวิธีที่ดีที่สุดในการทำเช่นนี้หรือวิธีการดาวน์โหลดไฟล์อย่างถูกต้อง?

ขอบคุณ!

แก้ไข 6/15/10

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

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

creativebe.com/icombiner/merge-jpg.html ฉันใช้โปรแกรมนั้นเพื่อรวมไฟล์. jpg ทั้งหมดไว้ใน PDF เดียว ทำงานได้ยอดเยี่ยมและฟรี!
Mike

7
ลองโพสต์โซลูชันของคุณเป็นคำตอบแล้วนำออกจากคำถาม โพสต์คำถามใช้สำหรับถามคำถามตอบโพสต์สำหรับคำตอบ :-)
BartoszKP

ทำไมนี้จะติดแท็กด้วยbeautifulsoup? โพสต์นี้แสดงอยู่ในรายการbeautifulsoupคำถามยอดนิยม
P0W

1
@ P0W ฉันลบแท็กที่กล่าวถึงแล้ว
kmonsoor

คำตอบ:


252

Python 2

ใช้urllib.urlretrieve

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

Python 3

ใช้urllib.request.urlretrieve (ส่วนหนึ่งของอินเทอร์เฟซดั้งเดิมของ Python 3 ทำงานเหมือนกันทุกประการ )

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

ดูเหมือนว่าฉันจะตัดนามสกุลไฟล์ของฉันเมื่อผ่านเป็นอาร์กิวเมนต์ (มีนามสกุลอยู่ใน URL ดั้งเดิม) มีความคิดอะไรไหม
JeffThompson

1
คุณทำใช่ ฉันคิดว่าฉันสันนิษฐานว่าหากไม่ได้รับนามสกุลไฟล์นามสกุลของไฟล์จะถูกต่อท้าย ในเวลานั้นมันก็สมเหตุสมผลสำหรับฉัน แต่ฉันคิดว่าตอนนี้ฉันเข้าใจว่าเกิดอะไรขึ้น
JeffThompson

65
หมายเหตุสำหรับ Python 3 คุณจะต้องนำเข้า [url.request] ( docs.python.org/3.0/library/ ...... ):import urllib.request urllib.request.retrieve("http://...")
wasabigeek

1
โปรดทราบว่ารายการเอกสาร Python 3 เรียกคืน () เป็นส่วนหนึ่งของ "Legacy Interface"และกล่าวว่าอาจเลิกใช้แล้วในอนาคต
Nathan Wailes

18
หมายเหตุสำหรับหลาม 3 import urllib.request urllib.request.urlretrieve("http://...jpg", "1.jpg")ก็จริง มันเป็นurlretrieveในขณะนี้เป็นของ 3.x.
user1032613


70

สำหรับบันทึกโดยใช้ไลบรารีคำขอ

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

แม้ว่ามันควรตรวจสอบข้อผิดพลาด requests.get ()


1
แม้ว่าวิธีนี้จะไม่ได้ใช้ urllib แต่คุณอาจใช้ไลบรารีคำขอในสคริปต์ python ของคุณอยู่แล้ว (นั่นคือกรณีของฉันในขณะที่ค้นหาสิ่งนี้) ดังนั้นคุณอาจต้องการใช้มันเพื่อรับรูปภาพของคุณด้วย
Iam Zesh

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

ไม่สามารถทำให้ urllib ทำงานได้ใน python3 คำขอไม่มีปัญหาและโหลดได้แล้ว! ทางเลือกที่ดีกว่าที่ฉันคิดไว้
user3023715

@ user3023715 ใน python3 คุณต้องนำเข้าคำขอจาก urllib ดูที่นี่
Yassine Sedrani

34

สำหรับ Python 3 คุณจะต้องนำเข้าimport urllib.request:

import urllib.request 

urllib.request.urlretrieve(url, filename)

สำหรับข้อมูลเพิ่มเติมตรวจสอบลิงค์



10

ฉันได้พบคำตอบนี้และฉันแก้ไขด้วยวิธีที่เชื่อถือได้มากขึ้น

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

จากนี้คุณจะไม่ได้รับทรัพยากรหรือข้อยกเว้นอื่นใดในขณะที่ดาวน์โหลด


1
คุณควรลบ 'self'
Euphe

8

หากคุณรู้ว่าไฟล์อยู่ในไดเรกทอรีเดียวกันdirของเว็บไซต์siteและมีรูปแบบดังต่อไปนี้: filename_01.jpg, ... , filename_10.jpg จากนั้นดาวน์โหลดทั้งหมด:

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()เพื่ออ่านการตอบกลับบางส่วนหรือทั้งหมดจากนั้นเขียนลงในไฟล์ที่คุณเปิดในตำแหน่งที่รู้จักดี


5

บางทีคุณอาจต้องการ 'ตัวแทนผู้ใช้':

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

3

นอกเหนือจากการแนะนำให้คุณอ่านเอกสารretrieve()อย่างละเอียด ( http://docs.python.org/library/urllib.html#urllib.URLopener.retrieve ) ฉันจะแนะนำให้โทรread()ไปยังเนื้อหาของการตอบสนองจริง ๆ แล้วบันทึกลงใน ไฟล์ที่คุณเลือกแทนที่จะปล่อยไว้ในไฟล์ชั่วคราวที่ดึงข้อมูลมาสร้าง


3

รหัสทั้งหมดข้างต้นไม่อนุญาตให้เก็บชื่อภาพดั้งเดิมซึ่งบางครั้งจำเป็นต้องใช้ ซึ่งจะช่วยในการบันทึกภาพลงในไดรฟ์ในเครื่องของคุณโดยคงชื่อภาพดั้งเดิมไว้

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

ลองนี้เพื่อดูรายละเอียดเพิ่มเติม


3

สิ่งนี้ใช้ได้กับฉันโดยใช้ python 3

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

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

วิธีที่ง่ายกว่าอาจเป็น (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;

โปรดใช้ความระมัดระวังเกี่ยวกับการใช้เปลือยยกเว้นเช่นเดียวกับที่เห็นstackoverflow.com/questions/54948548/...
AMC

1

เกี่ยวกับสิ่งนี้:

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

หากคุณต้องการการสนับสนุนพร็อกซี่คุณสามารถทำได้:

  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

อีกวิธีในการทำเช่นนี้คือผ่านห้องสมุด fastai สิ่งนี้ได้ผลเหมือนมนต์เสน่ห์สำหรับฉัน ฉันกำลังเผชิญกับการSSL: CERTIFICATE_VERIFY_FAILED Errorใช้งานurlretrieveดังนั้นฉันจึงพยายามอย่างนั้น

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

ฉันกำลังเผชิญหน้ากับ SSL: CERTIFICATE_VERIFY_FAILED ข้อผิดพลาด stackoverflow.com/questions/27835619/…
AMC

0

ใช้การร้องขอ

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 คุณสามารถทำสิ่งนี้ได้ทันที

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")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.