จะบันทึกภาพในเครื่องได้อย่างไรโดยใช้ Python ซึ่งมีที่อยู่ URL ที่ฉันรู้จักอยู่แล้ว


152

ฉันรู้ URL ของภาพบนอินเทอร์เน็ต

เช่นhttp://www.digimouth.com/news/media/2011/09/google-logo.jpgซึ่งมีโลโก้ของ Google

ตอนนี้ฉันจะดาวน์โหลดรูปภาพนี้โดยใช้ Python ได้อย่างไรโดยไม่ต้องเปิด URL ในเบราว์เซอร์และบันทึกไฟล์ด้วยตนเอง


คำตอบ:


316

Python 2

นี่คือวิธีที่ตรงไปตรงมามากขึ้นหากสิ่งที่คุณต้องการทำคือบันทึกเป็นไฟล์:

import urllib

urllib.urlretrieve("http://www.digimouth.com/news/media/2011/09/google-logo.jpg", "local-filename.jpg")

อาร์กิวเมนต์ที่สองคือพา ธ โลคัลที่ควรบันทึกไฟล์

Python 3

ตามที่ SergO แนะนำรหัสด้านล่างควรทำงานกับ Python 3

import urllib.request

urllib.request.urlretrieve("http://www.digimouth.com/news/media/2011/09/google-logo.jpg", "local-filename.jpg")

55
วิธีที่ดีในการรับชื่อไฟล์จากลิงค์คือfilename = link.split('/')[-1]
heltonbiker

2
ด้วย urlretrieve ฉันเพิ่งได้รับไฟล์ 1KB พร้อม dict และข้อความแสดงข้อผิดพลาด 404 อยู่ทำไมล่ะ? ถ้าฉันป้อน url ในเบราว์เซอร์ของฉันฉันจะได้รับรูปภาพ
Yebach

2
@Yebach: ไซต์ที่คุณดาวน์โหลดอาจกำลังใช้คุกกี้, User-Agent หรือส่วนหัวอื่น ๆ เพื่อกำหนดเนื้อหาที่จะให้บริการแก่คุณ สิ่งเหล่านี้จะแตกต่างกันระหว่างเบราว์เซอร์ของคุณกับ Python
Liquid_Fire

27
Python 3 : import urllib.requestและurllib.request.urlretrieve()ตาม
SergO

1
@SergO - คุณสามารถเพิ่ม Python 3 ในคำตอบเดิมได้หรือไม่?
Sreejith Menon

27
import urllib
resource = urllib.urlopen("http://www.digimouth.com/news/media/2011/09/google-logo.jpg")
output = open("file01.jpg","wb")
output.write(resource.read())
output.close()

file01.jpg จะมีภาพของคุณ


2
คุณควรเปิดไฟล์ในโหมดไบนารี: open("file01.jpg", "wb")ไม่เช่นนั้นรูปภาพอาจเสียหาย
Liquid_Fire

2
urllib.urlretrieveสามารถบันทึกภาพได้โดยตรง
heltonbiker

17

ฉันเขียนสคริปต์ที่ทำสิ่งนี้และมันมีอยู่ใน github ของฉันสำหรับการใช้งานของคุณ

ฉันใช้ BeautifulSoup เพื่อให้ฉันแยกวิเคราะห์เว็บไซต์เพื่อหารูปภาพ ถ้าคุณจะทำเว็บขูดมาก (หรือตั้งใจจะใช้เครื่องมือของฉัน) sudo pip install BeautifulSoupผมแนะนำให้คุณ ข้อมูลเกี่ยวกับ BeautifulSoup สามารถใช้ได้ที่นี่

เพื่อความสะดวกนี่คือรหัสของฉัน:

from bs4 import BeautifulSoup
from urllib2 import urlopen
import urllib

# use this image scraper from the location that 
#you want to save scraped images to

def make_soup(url):
    html = urlopen(url).read()
    return BeautifulSoup(html)

def get_images(url):
    soup = make_soup(url)
    #this makes a list of bs4 element tags
    images = [img for img in soup.findAll('img')]
    print (str(len(images)) + "images found.")
    print 'Downloading images to current working directory.'
    #compile our unicode list of image links
    image_links = [each.get('src') for each in images]
    for each in image_links:
        filename=each.split('/')[-1]
        urllib.urlretrieve(each, filename)
    return image_links

#a standard call looks like this
#get_images('http://www.wookmark.com')

11

สิ่งนี้สามารถทำได้ด้วยการร้องขอ โหลดหน้าและดัมพ์เนื้อหาไบนารีไปยังไฟล์

import os
import requests

url = 'https://apod.nasa.gov/apod/image/1701/potw1636aN159_HST_2048.jpg'
page = requests.get(url)

f_ext = os.path.splitext(url)[-1]
f_name = 'img{}'.format(f_ext)
with open(f_name, 'wb') as f:
    f.write(page.content)

1
ส่วนหัวของผู้ใช้ในคำขอหากได้รับคำขอที่ไม่ดี :)
1UC1F3R616


6

โซลูชันที่ใช้งานได้กับ Python 2 และ Python 3:

try:
    from urllib.request import urlretrieve  # Python 3
except ImportError:
    from urllib import urlretrieve  # Python 2

url = "http://www.digimouth.com/news/media/2011/09/google-logo.jpg"
urlretrieve(url, "local-filename.jpg")

หรือหากข้อกำหนดเพิ่มเติมของrequestsเป็นที่ยอมรับและเป็น URL http:

def load_requests(source_url, sink_path):
    """
    Load a file from an URL (e.g. http).

    Parameters
    ----------
    source_url : str
        Where to load the file from.
    sink_path : str
        Where the loaded file is stored.
    """
    import requests
    r = requests.get(source_url, stream=True)
    if r.status_code == 200:
        with open(sink_path, 'wb') as f:
            for chunk in r:
                f.write(chunk)

5

ฉันสร้างสคริปต์ให้กับสคริปต์ของ Yup ฉันแก้ไขบางสิ่ง ตอนนี้จะข้าม 403: ปัญหาที่ต้องห้าม มันจะไม่ผิดพลาดเมื่อไม่สามารถดึงภาพได้ พยายามหลีกเลี่ยงตัวอย่างที่เสียหาย ทำให้ได้ URL ที่ถูกต้องที่สุด ให้ข้อมูลเพิ่มเติม มันสามารถทำงานกับอาร์กิวเมนต์จากบรรทัดคำสั่ง

# getem.py
# python2 script to download all images in a given url
# use: python getem.py http://url.where.images.are

from bs4 import BeautifulSoup
import urllib2
import shutil
import requests
from urlparse import urljoin
import sys
import time

def make_soup(url):
    req = urllib2.Request(url, headers={'User-Agent' : "Magic Browser"}) 
    html = urllib2.urlopen(req)
    return BeautifulSoup(html, 'html.parser')

def get_images(url):
    soup = make_soup(url)
    images = [img for img in soup.findAll('img')]
    print (str(len(images)) + " images found.")
    print 'Downloading images to current working directory.'
    image_links = [each.get('src') for each in images]
    for each in image_links:
        try:
            filename = each.strip().split('/')[-1].strip()
            src = urljoin(url, each)
            print 'Getting: ' + filename
            response = requests.get(src, stream=True)
            # delay to avoid corrupted previews
            time.sleep(1)
            with open(filename, 'wb') as out_file:
                shutil.copyfileobj(response.raw, out_file)
        except:
            print '  An error occured. Continuing.'
    print 'Done.'

if __name__ == '__main__':
    url = sys.argv[1]
    get_images(url)

3

ใช้ไลบรารีคำขอ

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)


ImageDl(url)

ดูเหมือนว่าส่วนหัวมีความสำคัญอย่างยิ่งในกรณีของฉันฉันได้รับข้อผิดพลาด 403 ครั้ง มันได้ผล
Ishtiyaq Husain

2

นี่เป็นคำตอบสั้น ๆ

import urllib
urllib.urlretrieve("http://photogallery.sandesh.com/Picture.aspx?AlubumId=422040", "Abc.jpg")

2

รุ่นสำหรับ Python 3

ฉันปรับรหัสของ @madprops สำหรับ Python 3

# getem.py
# python2 script to download all images in a given url
# use: python getem.py http://url.where.images.are

from bs4 import BeautifulSoup
import urllib.request
import shutil
import requests
from urllib.parse import urljoin
import sys
import time

def make_soup(url):
    req = urllib.request.Request(url, headers={'User-Agent' : "Magic Browser"}) 
    html = urllib.request.urlopen(req)
    return BeautifulSoup(html, 'html.parser')

def get_images(url):
    soup = make_soup(url)
    images = [img for img in soup.findAll('img')]
    print (str(len(images)) + " images found.")
    print('Downloading images to current working directory.')
    image_links = [each.get('src') for each in images]
    for each in image_links:
        try:
            filename = each.strip().split('/')[-1].strip()
            src = urljoin(url, each)
            print('Getting: ' + filename)
            response = requests.get(src, stream=True)
            # delay to avoid corrupted previews
            time.sleep(1)
            with open(filename, 'wb') as out_file:
                shutil.copyfileobj(response.raw, out_file)
        except:
            print('  An error occured. Continuing.')
    print('Done.')

if __name__ == '__main__':
    get_images('http://www.wookmark.com')

1

มีอะไรใหม่สำหรับ Python 3 ที่ใช้คำขอ:

ความคิดเห็นในรหัส พร้อมใช้งานฟังก์ชั่น


import requests
from os import path

def get_image(image_url):
    """
    Get image based on url.
    :return: Image name if everything OK, False otherwise
    """
    image_name = path.split(image_url)[1]
    try:
        image = requests.get(image_url)
    except OSError:  # Little too wide, but work OK, no additional imports needed. Catch all conection problems
        return False
    if image.status_code == 200:  # we could have retrieved error page
        base_dir = path.join(path.dirname(path.realpath(__file__)), "images") # Use your own path or "" to use current working directory. Folder must exist.
        with open(path.join(base_dir, image_name), "wb") as f:
            f.write(image.content)
        return image_name

get_image("https://apod.nasddfda.gov/apod/image/2003/S106_Mishra_1947.jpg")

0

ตอบช้า แต่สำหรับpython>=3.6คุณสามารถใช้dloadได้เช่น:

import dload
dload.save("http://www.digimouth.com/news/media/2011/09/google-logo.jpg")

หากคุณต้องการภาพเป็นbytesใช้:

img_bytes = dload.bytes("http://www.digimouth.com/news/media/2011/09/google-logo.jpg")

ติดตั้งโดยใช้ pip3 install dload


-2
img_data=requests.get('https://apod.nasa.gov/apod/image/1701/potw1636aN159_HST_2048.jpg')

with open(str('file_name.jpg', 'wb') as handler:
    handler.write(img_data)

4
ยินดีต้อนรับสู่ Stack Overflow! ในขณะที่คุณอาจแก้ไขปัญหาของผู้ใช้คนนี้คำตอบแบบรหัสเท่านั้นไม่เป็นประโยชน์กับผู้ใช้ที่มาที่คำถามนี้ในอนาคต โปรดแก้ไขคำตอบของคุณเพื่ออธิบายสาเหตุที่รหัสของคุณแก้ปัญหาเดิม
Joe C

1
TypeError: a bytes-like object is required, not 'Response'. มันจะต้องเป็นhandler.write(img_data.content)
TitanFighter

handler.write(img_data.read())มันควรจะเป็น
jdhao
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.