Python3 Urllib映像下载返回HTTP错误403:禁止

时间:2018-09-02 08:18:42

标签: python python-3.x urllib

我正在研究一个python项目,需要从URL下载图像,我已经在Google上搜索了很多,并尝试了很多解决方案,但对我却没用。

  

已更新:现在,我将代码更新为:

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

现在,它下载图像并显示它,但不将其保存在   我的目录,这里出什么问题了?

下面是上一个/旧代码。

  

这是我尝试过的:

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

这是我的要求:

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

但是它返回此错误:

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 -
  

我也尝试使用http而不是https,但是它返回相同的错误。

请帮帮我!

谢谢!

2 个答案:

答案 0 :(得分:0)

必须在要发送的请求的标头中指定用户代理。

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

答案 1 :(得分:0)

在上一个答案中,我误解了您的问题,对不起。

img.show()

只会尝试在屏幕上显示图像,而不会将其保存到工作目录中。

您不会关闭已创建的文件,也不会将文件对象的链接分配给任何变量,因此创建后只是由垃圾收集器收集

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)

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)

现在应该解决您的问题(第一个使用上下文管理器with编写的变体,第二个是传统方法)
flask.send_file() docs

我还建议不要在服务器端使用img.show()(如果您已将项目部署到远程服务器,则不会有任何影响)