2017-01-04 14 views
1

私はPythonのurllib.requestを使っていくつかのコンテンツをダウンロードしようとしています。次のコマンドが例外を生成:なぜurllib.request.urlopenは動作しませんが、ブラウザは動作しますか?

import urllib.request 
print(urllib.request.urlopen("https://fpgroup.foreignpolicy.com/foreign-policy-releases-mayjune-spy-issue/").code) 

結果:

... 
HTTPError: HTTP Error 403: Forbidden 

私はオオヤマネコを使用している場合は、私がコンテンツと200のステータスコードを取得するFirefoxやリンク(コマンド・ライン・ブラウザ)を使用する場合、奇妙なことに、私はまた、私はすべてのメソッドが

  1. 同じよう
  2. 0123を動作することを期待403

    を取得します

  3. 正常に

なぜそうではないのですか?

+0

多分サイトブロックの人々。それを設定してみますか? – MooingRawr

+0

@MooingRawr:それは...それを答えてください。 – steffen

+0

も:誰が彼らを離れようとしていますか? – steffen

答えて

2

ほとんどの場合、サイトはユーザーが自分のサイトをスクラップするのをブロックしています。ヘッダー情報を他のものと一緒に含めることによって、基本レベルでそれらを欺くことができます。詳細はこちらをご覧ください。

から引用:https://docs.python.org/3/howto/urllib2.html#headers

import urllib.parse 
import urllib.request 

url = 'http://www.someserver.com/cgi-bin/register.cgi' 
user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' 
values = {'name' : 'Michael Foord', 
      'location' : 'Northampton', 
      'language' : 'Python' } 
headers = { 'User-Agent' : user_agent } 

data = urllib.parse.urlencode(values) 
data = data.encode('ascii') 
req = urllib.request.Request(url, data, headers) 
with urllib.request.urlopen(req) as response: 
    the_page = response.read() 

人々はスクリプトが自分のウェブサイトをこすりたくない多くの理由があります。帯域幅は1になります。彼らはスクラップボットを作って人々に利益をもたらすことを望まない(金銭的に)。たぶんあなたは自分のサイト情報をコピーしたくないかもしれません。あなたはそれを本と考えることもできます。著者は書籍を読んでもらいたいと思っていますが、ロボットの一部が書籍をスキャンしたり、オフコピーを作成したり、ロボットが要約したりすることは望ましくありません。

コメント内の質問の2番目の部分はあまりにも多くの意見の答えがあるので、ここで答えに漠然として広範になります。

+0

に答えました:それはむしろ改ざんな質問でした;) – steffen

2

私はこのコードを試してみましたが、大丈夫でした。

私はちょうど要求にheadersを追加しました。以下の例を参照してください:

from urllib.request import Request, urlopen, HTTPError 
from time import sleep 

def get_url_data(url = ""): 
    try: 
     request = Request(url, headers = {'User-Agent' :\ 
      "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36"}) 

     response = urlopen(request) 
     data = response.read().decode("utf8") 
     return data 
    except HTTPError: 
     return None 

url = "https://fpgroup.foreignpolicy.com/foreign-policy-releases-mayjune-spy-issue/" 

for i in range(50): 
    d = get_url_data(url) 
    if d != None: 
     print("Attempt %d was a Success" % i) 
    else: 
     print("Attempt %d was a Failure" % i) 
    sleep(1) 

出力:ヘッダ情報とすべてのものをチェックしてこするから

Attempt 0 was a Success 
Attempt 1 was a Success 
Attempt 2 was a Success 
Attempt 3 was a Success 
Attempt 4 was a Success 
Attempt 5 was a Success 
Attempt 6 was a Success 
Attempt 7 was a Success 
Attempt 8 was a Success 
Attempt 9 was a Success 
... 
Attempt 42 was a Success 
Attempt 43 was a Success 
Attempt 44 was a Success 
Attempt 45 was a Success 
Attempt 46 was a Success 
Attempt 47 was a Success 
Attempt 48 was a Success 
Attempt 49 was a Success 
+2

繰り返しリクエストをしてウェブサイトを氾濫させないでください。少なくともそれらの間には 'time.sleep'を使います。 – bfontaine

+0

私は各リクエストの間に 'time.sleep'を追加します。ご意見ありがとうございます。 –

+0

@bfontaine:私はしません。私は最初に新しい項目のRSSフィードをチェックしていて、特定のトピックの新しい記事だけをダウンロードしています。この問題は、最初にスクリプトを実行し、偶然にいくつかの記事を要求したときに発生しました。 – steffen

関連する問題