Python爬虫学习笔记:GET和POST请求两者抓取方式的异同

爬取网页信息必须弄清楚网页结构,今天来分析一下网页的两种访问方式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后面以拼接方式传参,但是如果参数是中文时需要转码处理,否则会报错。

比如我们访问豆瓣的官网,然后在搜索框中输入“电影”关键字:

可以看到浏览器中的请求为 douban.com/search? 电影

如果我们直接模拟上面的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()