Tải ảnh qua urllib và python


183

Vì vậy, tôi đang cố gắng tạo một tập lệnh Python tải xuống webcomics và đặt chúng vào một thư mục trên máy tính để bàn của tôi. Tôi đã tìm thấy một vài chương trình tương tự ở đây để làm một cái gì đó tương tự, nhưng không giống như những gì tôi cần. Một cái mà tôi thấy giống nhau nhất là ở ngay đây ( http://bytes.com/topic/python/answers/850927-probols-USE-urllib-doad-images ). Tôi đã thử sử dụng mã này:

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

Sau đó tôi đã tìm kiếm trên máy tính của mình một tập tin "00000001.jpg", nhưng tất cả những gì tôi tìm thấy là hình ảnh được lưu trong bộ nhớ cache của nó. Tôi thậm chí không chắc nó đã lưu tập tin vào máy tính của tôi. Khi tôi hiểu cách tải tệp xuống, tôi nghĩ tôi biết cách xử lý phần còn lại. Về cơ bản chỉ cần sử dụng một vòng lặp for và phân tách chuỗi tại '00000000'. 'Jpg' và tăng '00000000' lên đến số lớn nhất mà tôi phải xác định bằng cách nào đó. Bất kỳ đề xuất nào về cách tốt nhất để làm điều này hoặc làm thế nào để tải tập tin chính xác?

Cảm ơn!

EDIT 6/15/10

Đây là kịch bản hoàn thành, nó lưu các tập tin vào bất kỳ thư mục bạn chọn. Vì một số lý do kỳ lạ, các tệp không tải xuống và họ đã làm. Bất kỳ đề xuất về cách làm sạch nó sẽ được nhiều đánh giá cao. Tôi hiện đang tìm cách làm thế nào để tìm ra nhiều truyện tranh tồn tại trên trang web để tôi có thể lấy chỉ một cuốn mới nhất, thay vì bỏ chương trình sau khi một số ngoại lệ nhất định được nêu ra.

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

Ok, tôi đã có tất cả để tải về! Bây giờ tôi bị mắc kẹt với một giải pháp rất không phù hợp để xác định có bao nhiêu truyện tranh trực tuyến ... Về cơ bản, tôi đang chạy chương trình tới một số tôi biết là qua số lượng truyện tranh và sau đó chạy một ngoại lệ để xuất hiện khi truyện tranh không xuất hiện Không tồn tại và khi ngoại lệ xuất hiện hơn hai lần (vì tôi không nghĩ sẽ có nhiều hơn hai truyện tranh), nó thoát khỏi chương trình, nghĩ rằng không còn gì để tải xuống. Vì tôi không có quyền truy cập vào trang web, có cách nào tốt nhất để xác định có bao nhiêu tệp trên trang web không? Tôi sẽ đăng mã của tôi trong một giây.
Mike

creativebe.com/icombiner/merge-jpg.html Tôi đã sử dụng chương trình đó để hợp nhất tất cả các tệp .jpg vào một tệp PDF. Hoạt động tuyệt vời, và nó miễn phí!
Mike

7
Xem xét đăng giải pháp của bạn như một câu trả lời, và loại bỏ nó khỏi câu hỏi. Câu hỏi bài viết là để đặt câu hỏi, trả lời bài viết cho câu trả lời :-)
BartoszKP

Tại sao điều này được gắn thẻ beautifulsoup? Bài đăng này hiển thị trong danh sách beautifulsoupcâu hỏi hàng đầu
P0W

1
@ P0W Tôi đã xóa thẻ thảo luận.
kmonsoor

Câu trả lời:


252

Con trăn 2

Sử dụng urllib.urlretrieve

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

Con trăn 3

Sử dụng urllib.request.urlretrieve (một phần của giao diện kế thừa của Python 3, hoạt động giống hệt nhau)

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

Nó dường như đang cắt phần mở rộng tệp cho tôi khi được chuyển qua làm đối số (phần mở rộng có trong URL gốc). Bất cứ ý tưởng tại sao?
JeffThndry

1
Bạn có, có. Tôi nghĩ rằng tôi đã giả định rằng nếu không có phần mở rộng tập tin nào được đưa ra, phần mở rộng của tập tin sẽ được nối thêm. Nó có ý nghĩa với tôi vào thời điểm đó, nhưng tôi nghĩ bây giờ tôi hiểu những gì đang xảy ra.
JeffThndry

65
Lưu ý cho Python 3 bạn sẽ cần phải nhập khẩu [url.request] ( docs.python.org/3.0/library/... ):import urllib.request urllib.request.retrieve("http://...")
wasabigeek

1
Lưu ý rằng danh sách tài liệu Python 3 lấy () như một phần của "Giao diện kế thừa" và nói rằng nó có thể bị phản đối trong tương lai.
Nathan Wailes

18
Lưu ý cho Python 3 nó thực sự import urllib.request urllib.request.urlretrieve("http://...jpg", "1.jpg"). Đó là urlretrievebây giờ như của 3.x.
dùng1032613

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

70

Chỉ cần cho hồ sơ, sử dụng thư viện yêu cầu.

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

Mặc dù nó nên kiểm tra lỗi request.get ().


1
Ngay cả khi giải pháp này không sử dụng urllib, bạn có thể đã sử dụng thư viện yêu cầu đã có trong tập lệnh python của bạn (đó là trường hợp của tôi trong khi tìm kiếm này) vì vậy bạn cũng có thể muốn sử dụng nó để lấy ảnh của mình.
Iam Zesh

Cảm ơn bạn đã đăng câu trả lời này lên trên những người khác. Cuối cùng tôi đã cần các tiêu đề tùy chỉnh để tải xuống hoạt động và con trỏ đến thư viện yêu cầu đã rút ngắn quá trình làm cho mọi thứ hoạt động với tôi đáng kể.
kuzzooroo

Thậm chí không thể có được urllib để làm việc trong python3. Yêu cầu không có vấn đề và nó đã được tải! Sự lựa chọn tốt hơn nhiều tôi nghĩ.
dùng3023715

@ user3023715 trong python3 bạn cần nhập yêu cầu từ urllib xem tại đây
Yassine Sedrani

34

Đối với Python 3, bạn sẽ cần nhập import urllib.request:

import urllib.request 

urllib.request.urlretrieve(url, filename)

để biết thêm thông tin kiểm tra liên kết


15

Phiên bản Python 3 của câu trả lời @ DiGMi's:

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

10

Tôi đã tìm thấy câu trả lời này và tôi chỉnh sửa nó theo cách đáng tin cậy hơn

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

Từ điều này, bạn không bao giờ nhận được bất kỳ tài nguyên hoặc ngoại lệ nào khác trong khi tải xuống.


1
Bạn nên xóa 'cái tôi'
Euphe

8

Nếu bạn biết rằng các tệp được đặt trong cùng thư mục dircủa trang web sitevà có định dạng sau: filename_01.jpg, ..., filename_10.jpg sau đó tải xuống tất cả chúng:

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

Dễ dàng nhất là chỉ sử dụng .read()để đọc một phần hoặc toàn bộ phản hồi, sau đó viết nó vào một tệp bạn đã mở ở một vị trí tốt đã biết.


5

Có thể bạn cần 'Tác nhân người dùng':

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

Có lẽ trang không có sẵn?
Alexander


3

Tất cả các mã trên, không cho phép giữ nguyên tên ảnh gốc, đôi khi được yêu cầu. Điều này sẽ giúp lưu hình ảnh vào ổ đĩa cục bộ của bạn, giữ nguyên tên hình ảnh gốc

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

Hãy thử điều này để biết thêm chi tiết.


3

Điều này làm việc cho tôi bằng cách sử dụng python 3.

Nó nhận được một danh sách các URL từ tệp csv và bắt đầu tải chúng vào một thư mục. Trong trường hợp nội dung hoặc hình ảnh không tồn tại, nó sẽ lấy ngoại lệ đó và tiếp tục thực hiện phép thuật của nó.

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

Một giải pháp đơn giản hơn có thể là (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;

Hãy cẩn thận về việc sử dụng trần trừ như thế, xem stackoverflow.com/questions/54948548/ .
AMC

1

Cái này thì sao:

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

Nếu bạn cần hỗ trợ proxy, bạn có thể làm điều này:

  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

Một cách khác để làm điều này là thông qua thư viện fastai. Điều này làm việc như một cơ duyên đối với tôi. Tôi đã phải đối mặt với SSL: CERTIFICATE_VERIFY_FAILED Errorviệc sử dụng urlretrievevì vậy tôi đã thử nó.

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

Tôi đã phải đối mặt với SSL: CERTIFICATE_VERIFY_FAILED Lỗi stackoverflow.com/questions/27835619/ ám
AMC

0

Sử dụng yêu cầu

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

Sử dụng urllib, bạn có thể hoàn thành việc này ngay lập tức.

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")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.