2017-09-12 19 views
1

私の質問は、Python 3にurllibはモジュールについては、私が期待どおりurlopenは405エラー

import urllib.request 
import urllib.parse 

url = "https://google.com/search?q=stackoverflow" 
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'} 

try: 
    req = urllib.request.Request(url, headers=headers) 
    resp = urllib.request.urlopen(req) 
    file = open('googlesearch.txt.', 'w') 
    file.write(str(resp.read())) 
    file.close() 

except Exception as e: 
    print(str(e)) 

作品次のコードで返すとGoogleの内容を書き込みますファイル内で 'stackoverflow'を検索します。有効なUser-Agentを設定する必要があります。さもなければ、Googleはリクエストを許可せず、405 Invalid Methodエラーを返します。

私はそれは同じのUser-Agentと同じGoogle検索であるようなコード

import urllib.request 
import urllib.parse 

url = "https://google.com/search" 
values = {'q': 'stackoverflow'} 
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'} 

data = urllib.parse.urlencode(values) 
data = data.encode('utf-8') 

try: 
    req = urllib.request.Request(url, data=data, headers=headers) 
    resp = urllib.request.urlopen(req) 
    file = open('googlesearch.txt.', 'w') 
    file.write(str(resp.read())) 
    file.close() 

except Exception as e: 
    print(str(e)) 

の以下の部分は、最初のものと同じ出力を生成するべきだと思います。ただし、このコードでは、「HTTPエラー405:メソッドが許可されていません」というメッセージを含む例外がスローされます。

私の質問は次のとおりです。コードの2番目の部分で何が問題になっていますか?最初の出力と同じ出力を生成しないのはなぜですか?

+1

'data ='を使用すると、POST要求をしています...エンコードされた値をURLの末尾に追加したいと思います... –

答えて

3

GET要求ではなくPOST要求を送信しているため、405応答が返されます。 メソッドが許可されていませんはあなたのユーザーエージェントヘッダーとは関係ありません。これは不正な方法(get、post、put、head、options、patch、delete)でhttpリクエストを送信することです。

ここに文書化されているとして、あなたがリクエストコンストラクタでdata引数が含まれているためurllibははPOSTを送信します。

https://docs.python.org/3/library/urllib.request.html#urllib.request.Request

方法は、(使用されるHTTPリクエストメソッドを表す文字列でなければなりません例えば ​​'HEAD')。提供されている場合、その値はメソッド属性に格納され、get_method()によって使用されます。それ以外の場合は、デフォルトは「GET」、そうでない場合は「POST」です。

urllibではなく要求ライブラリを使用することを強くお勧めします。これははるかに賢明なAPIを持っているためです。

import requests 
response = requests.get('https://google.com/search', {'q': 'stackoverflow'}) 
response.raise_for_status() # raise exception if status code is 4xx or 5xx 
with open('googlesearch.txt', 'w') as fp: 
    fp.write(response.text) 

https://github.com/requests/requests

+0

ありがとう!代わりにリクエストライブラリを使用します。 – Morten

3

https://docs.python.org/3.4/howto/urllib2.html#data

あなたがデータ引数を渡さない場合、urllibははGETリクエストを使用しています。 1つの GETリクエストとPOSTリクエストが異なる方法は、多くの場合、 には、システムの状態を何らかの方法で変更するPOST要求があります。 (たとえば、tinweightの のWebサイトで注文しますスパムはあなたのドアに届けられます)。