web-dev-qa-db-ja.com

python urllibを使用してURLから画像をダウンロードするが、HTTPエラー403を受信する:禁止

python module "urllib.request"を使用してURLから画像ファイルをダウンロードしたいのですが、これは一部のWebサイト(mangastream.comなど)では機能しますが、別のWebサイト(mangadoom.co)では機能しません「HTTPエラー403:禁止されています」というエラーが表示されます。後者の場合、何が問題となり、どのように修正すればよいですか?

OSXでpython3.4を使用しています。

import urllib.request

# does not work
img_url = 'http://mangadoom.co/wp-content/manga/5170/886/005.png'
img_filename = 'my_img.png'
urllib.request.urlretrieve(img_url, img_filename)

エラーメッセージの終わりにそれは言った:

... 
HTTPError: HTTP Error 403: Forbidden

ただし、別のウェブサイトでは機能します

# work
img_url = 'http://img.mangastream.com/cdn/manga/51/3140/006.png'
img_filename = 'my_img.png'
urllib.request.urlretrieve(img_url, img_filename)

以下の投稿の解決策を試しましたが、mangadoom.coでは機能しません。

rllibとpythonを介して画像をダウンロードする

Pythonでリモートイメージをコピーするにはどうすればよいですか?

私の場合は画像をダウンロードすることなので、ここでのソリューションも適合しません。 rllib2.HTTPError:HTTPエラー403:禁止

非Pythonソリューションも歓迎します。あなたの提案は大歓迎です。

10
neobot

このWebサイトはurllibで使用されるユーザーエージェントをブロックしているため、リクエストで変更する必要があります。残念ながら、urlretrieveがこれを直接サポートしているとは思いません。

美しいrequestsライブラリの使用をお勧めします。コードは(from here )になります。

import requests
import shutil

r = requests.get('http://mangadoom.co/wp-content/manga/5170/886/005.png', stream=True)
if r.status_code == 200:
    with open("img.png", 'wb') as f:
        r.raw.decode_content = True
        shutil.copyfileobj(r.raw, f)

このWebサイトはrequestsユーザーエージェントを禁止していないようです。しかし、変更が必要な場合は簡単です。

r = requests.get('http://mangadoom.co/wp-content/manga/5170/886/005.png',
                 stream=True, headers={'User-agent': 'Mozilla/5.0'})

また関連: rllibでのユーザーエージェントの変更

22
Benoit Seguin

オープナーを構築できます。次に例を示します。

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)

url=''
local=''
urllib.request.urlretrieve(url,local)

ちなみに、次のコードは同じです:

(オープナーなし)

req=urllib.request.Request(url,data,hdr)   
html=urllib.request.urlopen(req)

(オープナービルド)

html=operate.open(url,data,timeout)

ただし、次を使用する場合はヘッダーを追加できません。

urllib.request.urlretrieve()

この場合、オープナーを作成する必要があります。

21
er.Zhu

私はターミナルのURLでwgetを試してみますが、うまくいきます:

wget -O out_005.png  http://mangadoom.co/wp-content/manga/5170/886/005.png

だから私の回避策は、以下のスクリプトを使用することであり、それも機能します。

import os
out_image = 'out_005.png'
url = 'http://mangadoom.co/wp-content/manga/5170/886/005.png'
os.system("wget -O {0} {1}".format(out_image, url))
6
neobot