简体   繁体   中英

Python3 Urllib image download return HTTP Error 403: Forbidden

I'm working on a python project in which I need to download an image from a URL, I have googled a lot and tried tons of solutions but couldn't worked for me.

Updated: Now I have updated my code as:

from PIL import Image
from flask import Flask
import requests
app = Flask(__name__)


@app.route('/<path:image_url>')
def grab_image(image_url):
    url = str(image_url)
    r = requests.get(url, allow_redirects=True)
    print('Url is as: {}'.format(url))
    filename = url.split('/')[-1]
    open(filename, 'wb').write(r.content)
    img = Image.open(filename)
    img.show()
    return img


if __name__ == '__main__':
    app.run()

Now, it downloads the image and show it, but not saving the image in my directory, what's can be wrong here?

Below is the previous/old code.

Here's what I have tried:

from flask import Flask
import urllib.request
app = Flask(__name__)


def download_img(image_url, file_path, file_name):
    full_path = file_path + file_name + '.jpg'
    urllib.request.urlretrieve(image_url, full_path)
    pass


@app.route('/<path:image_url>')
def hello_world(image_url):
    file_name = 'async'
    download_img(image_url, 'img/', file_name)
    return 'Hello World!'


if __name__ == '__main__':
    app.run()

Here's my request:

http://127.0.0.1:5000/https://www.thelaurelmagazine.com/sites/default/files/styles/hero_image/public/mary_abryani_highlands_nc_yoga.jpg

But it returns this error:

urllib.error.HTTPError: HTTP Error 403: Forbidden
127.0.0.1 - - [02/Sep/2018 13:13:57] "GET /https://www.thelaurelmagazine.com/sites/default/files/styles/hero_image/public/mary_abryani_highlands_nc_yoga.jpg HTTP/1.1" 500 -

I have also tried with http instead of https but it returns the same error.

Help me, please!

Thanks in advance!

An user agent has to be specified in the headers in the request that you are sending.

from flask import Flask
import urllib.request
from PIL import Image
app = Flask(__name__)

user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'


def download_img(image_url, file_path, file_name):
    full_path = file_path + file_name + '.jpg'
    headers={'User-Agent':user_agent,} 
    request=urllib.request.Request(image_url,None,headers)
    response = urllib.request.urlopen(request)
    #install PIL package to convert the response into a PIL Image object to further save it
    image=Image.open(response)
    image.save(full_path)
    pass


@app.route('/<path:image_url>')
def hello_world(image_url):
    file_name = 'async'
    download_img(image_url, 'img/', file_name)
    return 'Hello World!'


if __name__ == '__main__':
    app.run()

In previous answer I've misunderstood your problem, sorry.

img.show()

Will only try to show the image on a screen, it does not save it to the working directory.

You don't close the file You've created and don't assign file object's link to any variable so it's just collected by garbage collector after creation

url = str(image_url)
r = requests.get(url, allow_redirects=True)
print('Url is as: {}'.format(url))
filename = url.split('/')[-1]
with open(filename, 'wb') as file:
    file.write(r.content)
return send_file(filename)

or

url = str(image_url)
r = requests.get(url, allow_redirects=True)
print('Url is as: {}'.format(url))
filename = url.split('/')[-1]
file = open(filename, 'wb')
file.write(r.content)
file.close()
return send_file(filename)

should solve your problem now (first variant written used context manager with , second is traditional approach)
flask.send_file() docs

Also i recommend not to use img.show() on server side (it will have no affect if You have deployed your project to a remote server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM