我的问题是关于python 3中的urllib模块。以下代码
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错误。
我认为以下一段代码
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))
应该生成与第一个相同的输出,因为它是使用相同User-Agent的相同Google搜索。但是,这段代码会抛出一条消息异常:'HTTP Error 405:Method Not Allowed'。
我的问题是:第二段代码出了什么问题?为什么它不能产生与第一个相同的输出?
答案 0 :(得分:3)
您收到405响应,因为您正在发送POST请求而不是GET请求。 不允许的方法不应与您的用户代理标头有任何关系。它是关于使用不正确的方法发送http请求(get,post,put,head,options,patch,delete)。
Urllib发送POST是因为您在Request构造函数中包含了data
参数,如下所示:
方法应该是一个字符串,表示将要使用的HTTP请求方法(例如'HEAD')。如果提供,则其值存储在method属性中,并由get_method()使用。如果数据为None,则默认为'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://docs.python.org/3/library/urllib.request.html#urllib.request.Request
答案 1 :(得分:3)
https://docs.python.org/3.4/howto/urllib2.html#data
如果未传递data参数,urllib将使用GET请求。一 GET和POST请求不同的方式是POST请求经常 有“副作用”:它们以某种方式改变系统的状态 (例如,通过网站下订单为百分之一 罐装垃圾邮件送到你家门口。)