4.Requests模块

明廷盛 嘻嘻😁

第一章 Requests基本方法

第一节 requests常用能发送请求的

  • 请求: get()/post()/…
序号类型如何获取区别
requests模块import requests最普通的
<requests.sessions.Session>session = requests.session()携带服务器发来的cookie信息, 进行请求

第二节 常见返回值处理

序号常用方法作用什么时候用
result .text返回以文本格式(HTML代码)页面的HTML代码
==②==result .content返回以二进制格式页面只有,图片,音频,视频
result .json()返回以json格式页面只有JSON数据
result .status_code返回此次请求服务器返回的状态码
==⑤==result .headers获取**响应头**
==⑥==result .request.hearders获取该次请求的**请求头**request的头部,有cookie
result .cookies获取cookies可以强转为字典
result.content.decode(“指定编码”)先返回二进制, 然后自定义解码获取html源码页面的HTML代码

第三节 python的解码和编码

方法作用
byte类型数据.encode(“编码格式”)将二进制数据**编码为**指定编码格式
byte类型数据.decode(“编码格式”)将二进制数据**解码为**指定编码格式

第二章 自定义请求头参数的请求headers

第一节 为什么要设置请求头

  • 原因: 当我们使用requests模块进行页面请求时, 其中User-Agent: python-requests/2.18.4这是默认的User-Agent的请求, 那不就等于告诉百度, 我是爬虫了, 肯定不行
  • 如何获取发送请求的请求头???: 见⑥

第二节 如何设置请求头

  • 语法: .get(..., headers=my_hearder) : 其中my_hearder是字典类型
1
2
3
4
5
6
7
aim_url = "https://www.baidu.com/"
my_header = { # 1.设置请求头
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
}
response = requests.get(aim_url, headers=my_header) # 2.get方法中传入请求头

print(response.content.decode())

第三章 发送GET请求get() params

需求: 在发送请求的同时, 携带”请求参数”

第一节 方式一: 问号拼接

  • 语法: 问号拼接, 不多说了; 回顾一点GET是默认的是拼接在地址栏的(flask框架)
1
2
3
aim_url = "https://www.baidu.com/s?word=python"
response = requests.get(aim_url, headers=my_header)
print(response.content.decode())

第二节 ==方式二==: 指定get()的params参数

  • 语法: .get(..., params=my_params) : 其中my_params是字典类型; 等同于在末尾拼接问号
1
2
3
4
5
6
aim_url = "https://www.baidu.com/s"
my_params = {
"word": "python"
}
response = requests.get(aim_url, headers=my_header, params=my_params) # 1.指定参数
print(response.content.decode())

第四章 发送POST请求post() data

需求: 爬取巨潮资讯网页面中的主体信息内容 (这个网站比较松, data,params都能爬,

但请注意params与get()请求连用(拼接地址栏); data与post()请求连用(表单隐藏发送)

第一节 整体流程

4.1.1 整体流程

  1. 用户点击”下一页”的按钮
  2. 前端ajax向指定后端服务器URL发送”下一页请求”POST
  3. 后端服务器根据URL地址,调用对应的方法
  4. 后端将从数据库查询好的数据, 返回给ajax,以JSON的格式
  5. 前端ajax对请求进行处理, 并展示在页面上

4.1.2 流程关键点

  1. 后端服务器URL是什么? 知道了这个,我们requests模拟发送即可
  2. 需要携带什么参数? 只有携带对应的参数, 方法才能响应,否则容易403

第二节 如何找两个关键点

4.2.1 如何找后端服务器URL

4.2.2 需要携带什么参数

我们自己写前后端的时候, 是不是要提交一个表单给后端, 所以我们的目标就是**模拟提交一样的字段**

第三节 发送POST请求post()使用 data传参

4.3.1 GET和POST的区别

  • & 语法:
ins
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests

headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
}
url = "https://cmsauth.baowugroup.com/v1/web/api/content/list"
# "查询字符串参数
params = {
"domainId": "12"
}
# "请求载荷"
data = {
"pageNo": 3,
"pageSize": 12,
"condition": {
"nodeId": 436
}
}
# 像这里, 就采用的json=字典进行传参
response = requests.post(url, headers=headers, params=params, json=data, verify=False)

print(response.text)
print(response)

4.3.2 两种传载荷方式data= VS json=

特性data=json=
数据类型(python)strdict
序列化方式需手动json.dumps()requests自动帮你json.dumps()
Content-Type默认application/x-www-form-urlencoded自动设置为application/json
文件上传支持(需特殊格式)不支持
  • $ 语法: 如下两种方式是一样的
  • ! 注意: 无论, 用哪个, 本质上都会json.dumps()以下, 区别只是一个手动, 一个自动
1
2
3
4
5
6
7
8
9
10
data = {
"pageNo": 3,
"pageSize": 12,
"condition": {
"nodeId": 436
}
}

response = requests.post(url, headers=headers, params=params, data=json.dumps(data), verify=False) # 使用 data=
response = requests.post(url, headers=headers, params=params, json=data, verify=False) # 使用 json=

第五章 使用IP代理发送请求proxies

因为同一个IP一直访问, 会被封, 所以得需要代理IP来访问, 下面将**如何使用代理IP发送请求**

需求: 分别使用代理不使用代理,获取IP查询网站所返回的数据

第一节 如何设置代理

  • 语法: get(proxies=my_proxies): my_proxies是字典类型&&必须为{代理协议:端口}
  • 代理的协议: ①http ②https ③socket
1
2
3
4
5
6
7
aim_url = "https://httpbin.org/ip"
my_proxies = { # 1.代理是字典
"http": "http://127.0.0.1:10808"
}
response = requests.get(aim_url, proxies=my_proxies) # 2.设置代理数据
print(response.json())

第六章 发送携带Cookie的请求cookies

需求: 发送请求的时候携带 cookies

需求: 在CSDN的个人信息页面获取个人头像的图片

第一节 ==方式一==: 在headers中设置

  • 语法: headers传递的字典中设置键值Cookie
1
2
3
4
5
6
7
8
9
10
11
12
13
import requests

aim_url = "https://msg.csdn.net/v1/web/message/view/unread" # CSDN的个人信息页面

# 请求头中携带cookies
my_header = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Cookie": "太长了, 自己去抓包复制"
}

response = requests.post(aim_url, headers=my_header) # 1.注意是请求头
print(response.json())

第二节 方式二: 单独设置cookies

  • 语法:get(cookies=my_cookies) :去把每个cookie分开, 写成键值对的形式, 太多了不推荐这种方式

image-20241129145125559

第七章 关于Session session.请求()

第一节 浏览器状态记录 基础知识回归

  • ①会话指的是这个标签的关闭, 不是整个浏览器关闭, 重新访问这个网站就已经是第二个会话了, 但重新roll这个网站还是当前会话
  • ②Cookie是保存在浏览器端的, Session是保存在服务器端的(但浏览器端要用Cookie保存session_id)
  • ③Cookie的有效时间是在new Cookie()出来对象的时候设置的(-1永久,0失效,>0s), 这个时间将带着到浏览器储存
  • ④Session的有效时间是同一的, 通过request.getSession()获取到session后, session.setMaxIntervi() (s为单位, 30min默认)

第二节 爬虫涉及到的相关知识

  • ①只有请求头中才有Cookie;
  • ②请求头中没有Session; Session是服务器端的, 浏览器端只以一个cookie的形式保存一个Session_id,来和服务器取得认可
  • 请求Cookie表示的是: 浏览器发送给服务器的cookie(可能是userinfo,后续的session_id..)
  • 响应Cookie表示的是: 服务器发送给浏览器的Cookie(可能是首次访问, 要服务器制作好的session_id发给浏览器)

==第三节 使用session请求的特殊之处==

  • 类型:<class 'requests.sessions.Session'>
  • 获取: session = requests.session()
  • 特殊之处: 携带服务器发来的cookie信息, 进行请求
    • 下面这个例子: 先是通过访问官网获取到了SESSIONID, 这样一来使用这个SESSIONID就可以访问一次后端API, 每次访问后端API前都会先访问官网地址, 等同与拿到一个一次性的KEY;
1
2
3
4
5
6
7
8
9
10
11
index_url = "http://www.cninfo.com.cn/new/index"  # 官网地址
api_url = "http://www.cninfo.com.cn/new/disclosure" # 爬取数据的接口

# 1.获取session对象
session = requests.session()
res = session.get(index_url) # 一. 通过它向官网发送一次数据,session会保存,服务器传来来的cookie(也就是SESSIONID)
session_id = res.cookies.get("JSESSIONID")
"""...中间代码有省略""""
# 2.发送请求
result = session.post(api_url) # 二. 后续使用session发请求时,都会更新这个cookie信息(如果变动的话),并携带发送其他请求
print(result.cookies)

第四节 什么时候会用到session

需求: 假设这个如下网站符合 一个SESSIONID只能使用进行一次后端接口的调用;(当然这个网站很松,但SESSIONID每次都在变,但一个可以用好多次🤣)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
index_url = "http://www.cninfo.com.cn/new/index"  # 官网地址
api_url = "http://www.cninfo.com.cn/new/disclosure" # 爬取数据的接口

# 1.获取session对象
session = requests.session()
res = session.get(index_url)
session_id = res.cookies.get("JSESSIONID") # 就是session_id,每个网站的开发人员的命名习惯不同

# 2.发送请求(有些网站可能因为session_id是动态的,每次都要校验,一直发同一个是无法得到数据的,只是这个网站比较松)
my_headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
}
my_data = {
"column": "szse_latest",
"pageNum": "3",
"pageSize": "30",
"sortName": "",
"sortType": "",
"clusterFlag": "true",
}
result = session.post(api_url, headers=my_headers, data=my_data) #这里发送请求的时候, 就会带上cookie(session_id)

if result.status_code == 200:
print(result.json())
else:
print(result.status_code)

第八章 证书忽略 verify

第一节 简单的证书错误

需求: 爬取这个网站的主页面内容(当然这个网站崩了, 但错误警告还是在的)

  • 语法: result = requests.get(aim_url,verify=False)请求的时候加上这个verify=False即可
  • 错误类型: requests.exceptions.SSLError 如果存在证书错误警告, 会报这个错
  • 其他: 出现如下报错, 正常, 安全警告而已
    1
    InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. 
1
2
3
4
5
6
7
aim_url = "https://yjcclm.com/"
try:
result = requests.get(aim_url)
except requests.exceptions.SSLError as e:
result = requests.get(aim_url,verify=False) # 1.请求时指定verify变量为False

print(result.content.decode())

第二节 dh key too small

原解决地址:link

STEP1: urllib3降级

  • & 说明: 如果出现execjs用不了, 就继续降, 降到1.24.3
    50e6d897b12e9487bb88f738177b798.png|575
1
pip  install urllib3==1.25.6 

STEP2: 完全让urllib3忽略那些安全问题

ins
1
2
3
4
5
6
7
8
9
10
11
12
import requests
import urllib3

requests.packages.urllib3.disable_warnings()
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':HIGH:!DH:!aNULL'
try:
requests.packages.urllib3.contrib.pyopenssl.util.ssl_.DEFAULT_CIPHERS += ':HIGH:!DH:!aNULL'
except AttributeError:
# no pyopenssl support used / needed / available
pass

page = requests.get(url, verify=False)

第九章 请求重试@retrying.retry()

需求: 如果网页的返回的状态码不是200, ①就重试3次访问, 如果还是不行, 抛出异常 ②否则打印网页内容

  • 语法: @retrying.retry(stop_max_attempt_number=重试次数n): retrying包需要自己下
  • 作用: 对该方法重试n次, 如果还是抛异常,就直接抛出, 其中只要有一次成功(没有抛出异常)就继续执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
import retrying

@retrying.retry(stop_max_attempt_number=3)
def get_access(url):
print("重新连接....")
result = requests.get(url)
assert result.status_code == 200, "状态码不正确" # ps:这里每打印是因为上面因为证书的问题,提前报错了
return result

if __name__ == '__main__':
aim_url = "https://yjcclm.com/"
result = get_access(aim_url) # 一. 这里如果返回不是200, 就报错
print(result.content.decode()) # 二. 否则打印网页内容

第十章 作业

需求: 爬取 百度图片 封装一个方法, ①传入搜索关键字key_word ②保存n页的图片 ③将抓取的图片保存在./image/中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# =================================
# @Time : 2024年11月30日
# @Author : 明廷盛
# @File : 14.作业(爬取百度图片).py
# @Software: PyCharm
# @ProjectBackground: 15min内爬取 [百度图片](https://image.baidu.com/) 封装一个方法, ①传入搜索关键字key_word ②将抓取的图片保存在./image/中 (不用管照片数量)
# =================================

import requests
import uuid


def get_baidu_image(key_word, num=30):
aim_url = "https://image.baidu.com/search/acjson";
header = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
}
params = { # GET请求, 用params
"tn": "resultjson_com",
"logid": "7424101381001970871",
"ipn": "rj",
"ct": "201326592",
"is": "",
"fp": "result",
"fr": "",
"word": key_word, # 这个主要控制 搜索内容(下面不是)
"queryWord": key_word,
"cl": "2",
"lm": "",
"ie": "utf-8",
"oe": "utf-8",
"adpicid": "",
"st": "-1",
"z": "",
"ic": "0",
"hd": "",
"latest": "",
"copyright": "",
"s": "",
"se": "",
"tab": "",
"width": "",
"height": "",
"face": "0",
"istype": "2",
"qc": "",
"nc": "1",
"expermode": "",
"nojc": "",
"isAsync": "",
"pn": 2, # 第几页
"rn": 60, # 每页的图片数量(经测试每页最多60张图片)
"gsm": "1e",
"1732933641118": "",
}

result = requests.get(aim_url, headers=header, params=params)
# 处理数据
json_result = dict(result.json())
print(len(json_result.get("data")))
index=1
for i in json_result.get("data"):
pic_url = i.get("thumbURL")
if pic_url is not None:
print(str(index) + ": " + pic_url)
index += 1
download_and_save_pic(pic_url)


def download_and_save_pic(pic_url):
result = requests.get(pic_url)
image_b = result.content # 图片的二进制文件
with open("./image/" + str(uuid.uuid1()) + ".png", "wb") as f:
f.write(image_b)


if __name__ == '__main__':
get_baidu_image("原神", 1)

  • Title: 4.Requests模块
  • Author: 明廷盛
  • Created at : 2025-02-15 14:34:49
  • Updated at : 2025-02-09 15:54:00
  • Link: https://blog.20040424.xyz/2025/02/15/🐍爬虫工程师/第一部分 爬虫基础/4.Requests模块/
  • License: All Rights Reserved © 明廷盛