python爬虫遇到的坑1——关于urllib.request.Request中的data参数

今天在写爬虫的时候死活运行不了

import urllib.request
import urllib.parse

#自定义页码
page = int(input('请输入页码:'))
if page < 1:
    print('页码输入错误,请输入大于等于1的数字')

#网页URL
url = 'https://maoyan.com/films?showType=3&'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88     Safari/537.36'
}

P = (page - 1) * 30

data = {
    'offset': P
}

#data转化为电脑能识别的二进制格式
data = urllib.parse.urlencode(data).encode('utf-8')

#请求
request = urllib.request.Request(url, data=data, headers=headers)

response = urllib.request.urlopen(request)

print(response.getcode())

#读取结果,并保存
content = response.read().decode('utf-8')

with open('maoyan.html', 'w', encoding='utf-8') as fp:
    fp.write(content)

死活运行不了,报错

urllib.error.HTTPError: HTTP Error 404: Not Found

后来又在网上查资料,折腾了好久,终于知道哪里错了


原来我需要先把“url”和“data”这两个网址做一个组合,把他们加起来,变成一个统一的网址:
//注意,这里‘https://maoyan.com/films?showType=3&’是我原本的url,而‘offset=30’是我data
里的内容

组合后的网址:
https://maoyan.com/films?showType=3&offset=30

然后再把他们写进request这个变量里头
这里data就不用要了,否则加上‘data=data’之后还会报错:

TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.

为什么报错呢,因为data参数是用来提交表单数据的,而这里的“offset=30”不能被当做表单数据提交,所以这里data就需要删去。
所以只能通过拼接网址的形式来访问。


放最终代码

import urllib.request
import urllib.parse

page = int(input('请输入页码:'))
if page < 1:
    print('页码输入错误,请输入大于等于1的数字')

url = 'https://maoyan.com/films?showType=3&'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88     Safari/537.36'
}

P = (page - 1) * 30

data = {
    'offset': P
}

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

#这里注意哈,现在data已经变成二进制格式了,所以我们只能通过把它转换成字符串格式才能和url拼接,也只有这样urllib.request.Request里的url参数才能识别我们拼接后的url
url = url + data

request = urllib.request.Request(url=url, headers=headers)

response = urllib.request.urlopen(request)

print(response.getcode())

content = response.read().decode('utf-8')

with open('maoyan.html', 'w', encoding='utf-8') as fp:
    fp.write(content)

然后还有一点需要注意,就是
data = urllib.parse.urlencode(data)

一定要注意urlencode解码,要是不加这个的话,data就永远是字典格式,而不是电脑可以识别的bytes二进制格式,在可以用data传参的POST请求的情况下,也没法完成访问。
注:“url”参数默认是“str”格式的。


版权声明:本文为qq_43654105原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。