爬取网页信息必须弄清楚网页结构,今天来分析一下网页的两种访问方式get和post。
1、HTTP请求方法
在客户机和服务器之间进行请求-响应时,两种最常被用到的方法是:GET 和 POST。
GET - 从指定的资源请求数据;
POST - 向指定的资源提交要被处理的数据;
两者的比较:
2、下面具体来看一下这两者抓取方式的异同;
(1)Get方式
GET方法是最常见也是最简单的,HTTP默认的请求方法就是GET。
一般用于我们向服务器获取数据,可以直接将URL输入,不需要其它的转换,即所有需要请求的信息都包含在URL中。
* 没有请求体
* 数据必须在1K之内!
* GET请求数据会暴露在浏览器的地址栏中
有关get请求的其他一些注释:
-
get 请求可被缓存
-
get 请求保留在浏览器历史记录中
-
get 请求可被收藏为书签
-
get 请求不应在处理敏感数据时使用
-
get 请求有长度限制
-
get 请求只应当用于取回数据(不修改)
常用的操作:
① 在浏览器的地址栏中直接给出URL,那么就一定是GET请求;
② 点击页面上的超链接也一定是GET请求;
③ 提交表单时,表单默认使用GET请求,但可以设置为POST;
get请求就是在url后面以拼接方式传参,但是如果参数是中文时需要转码处理,否则会报错。
比如我们访问豆瓣的官网,然后在搜索框中输入“电影”关键字:
可以看到浏览器中的请求为
https://www.
douban.com/search?
q=
电影
如果我们直接模拟上面的url请求,则会报如下错误:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 14-15: ordinal not in range(128)
原因是使用浏览器访问时,它会自动帮我们进行参数转码处理,而现在我们用代码访问,所以需要自己处理。
from urllib.request import urlopen
from urllib.request import Request
from random import choice
# 1.爬取站点访问地址
url = "https://www.douban.com/search?q=电影"
# 2.模拟多个浏览器的User-Agent(分别为Chrome、Firefox、Edge)
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763"
# 3.随机设置请求头信息
headers = {
"User-Agent": choice(user_agents)
# 4.将请求头信息封装到Request对象中
req = Request(url, headers=headers)
# 5.发送请求并打印返回值
print(urlopen(req).read().decode())
修改,然后引入urlencode函数对url进行参数转码就可以正常访问了;
省略..
from urllib.parse import urlencode
# 1.爬取站点访问地址
args = {'q': '电影'}
url = "https://www.douban.com/search?{}".format(urlencode(args))
省略...
从这些可以看出get方法获取到的内容是稳定的(即每个人打开某个网页获得的信息相同),但使用post需要输入特定信息,那么得到的网页内容就会有特异性,这一块下面我们会接着讲到。
单靠文字表述可能不是很好去理解,建议大家入门的时候最好能看一些配套的视频,加深对基础概念的印象,之后在实操环节也可以更好地理解每一步操作的含义。
这里给大家推荐一个可白嫖的学习公开课,点击下方即可跳转
<新手Python学习公开课 点击跳转>
(2)Post方式
post用于将数据发送到服务器来创建/更新资源。
通过post发送到服务器的数据存储在 HTTP 请求的请求主体中:
POST /test/demo_form.php HTTP/1.1
Host: w3school.com.cn
name1=value1&name2=value2
post要获取的内容只靠网址是不能获取到的,需要提交一些额外的信息。
这种信息在不同的网页中发挥不同功能,例如在查询天气的网页,可能就是要输入城市信息;在登录某些网页时,又是账号和密码的载体。
post请求:
① 数据不会出现在地址栏中
② 数据的大小没有上限
③ 有请求体
④ 请求体中如果存在中文,会使用URL编码!
有关post请求的其他一些注释:
-
post 请求不会被缓存
-
post 请求不会保留在浏览器历史记录中
-
post 不能被收藏为书签
-
post 请求对数据长度没有要求
一般HTTP请求提交数据,需要编码成URL编码格式,然后做为URL的一部分,或者作为参数传到Request对象中。
特殊点:
Request请求对象里有data参数,而post请求通过Request对象中的data属性来传参,用来存放请求体数据。
data是一个字典,里面要有匹配键值对。
我们这里模拟一个登录请求:
from urllib.request import urlopen
from urllib.request import Request
from random import choice
from urllib.parse import urlencode
# 1.url与参数处理
url = "https://www.douban.com/"
args = {
'name': 'abcdef123456',
'password': '123456'
# 2.模拟多个浏览器的User-Agent(分别为Chrome、Firefox、Edge)
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763"
# 3.随机设置请求头信息
headers = {
"User-Agent": choice(user_agents)
# 4.将请求头信息封装到Request对象中
req = Request(url, headers=headers, data=urlencode(args).encode())
# 5.发送请求并打印返回值
print(urlopen(req).read().decode())
如果不加encode()函数会报错误:
TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.
Post请求做一个百度翻译:
import urllib.request as ur
import urllib.parse as up
import json
word= input('请输入要翻译的英语:')
data={
'kw':word
data_url = up.urlencode(data)
request = ur.Request(url='https://fanyi.baidu.com/sug',data=data_url.encode('utf-8'))
reponse = ur.urlopen(request).read()