当前位置: 首页 > news >正文

Python 爬虫项目:GET 与 POST 请求详解

前言

HTTP 协议定义了多种请求方法,其中GETPOST是互联网应用中使用频次最高的两种方式,也是爬虫开发必须熟练掌握的核心内容。上一章节完成了 requests 库基础 GET 请求的实战演练,本章将从协议规范、应用场景、底层差异、代码实现、参数传递格式等维度,对 GET 与 POST 请求进行系统性拆解,同时结合真实业务场景完成多类型 POST 请求开发,并对比两类请求的选型原则与避坑要点。

在日常网络交互中,网页浏览、内容查询、资源加载多采用 GET 请求;账号登录、表单提交、数据上传、接口交互、评论发布等主动向服务器提交数据的场景,几乎全部依赖 POST 请求。二者在参数传输位置、数据大小限制、缓存机制、安全性、编码规则上存在本质区别,若混用请求方式,会直接导致爬虫请求失效、数据提交失败、登录状态无法维持等问题。

本章配套大量可直接运行的代码案例,结合 HTTP 报文原理、参数解析逻辑、异常场景处理进行讲解,同时区分表单数据、JSON 数据、文件上传等不同 POST 提交形式,覆盖爬虫开发中 99% 的请求场景。文中相关参考链接如下:

  1. HTTP 协议官方规范参考:https://www.rfc-editor.org/rfc/rfc9110.html
  2. HTTP 在线测试接口:https://httpbin.org/
  3. JSON 数据格式标准文档:https://www.json.org/

一、GET 与 POST 请求核心理论差异

在编写代码之前,首先明确两类请求的协议定义、核心区别与适用边界,从底层理解请求逻辑,避免开发中出现方向性错误。本节整理二者在传输机制、使用规范、特性表现上的核心差异,并结合爬虫场景说明影响。

1.1 核心特性对比表

表格

对比维度GET 请求POST 请求爬虫开发影响
参数传输位置参数拼接在URL 地址栏,跟随请求行发送参数放置在请求体(Request Body)中,独立传输GET 参数直接可见,POST 参数无法从 URL 直观查看
数据长度限制受浏览器、服务器对 URL 长度限制,一般不超过 2KB理论无长度限制,仅受服务器配置影响长文本、大体积数据、文件上传必须使用 POST
缓存机制默认被浏览器、代理服务器缓存,重复访问读取缓存默认不启用缓存,每次请求都会与服务器交互实时数据采集建议优先 POST,避免缓存造成数据陈旧
书签与历史记录URL 完整保留,可保存为书签、记录在浏览历史参数不在 URL 中,无法通过书签记录提交内容登录类 POST 请求不会泄露提交的账号密码
编码方式仅支持 ASCII 字符,中文、特殊符号需 URL 编码支持多种编码格式,适配表单、JSON、二进制等数据复杂数据提交、中文大批量传参优先使用 POST
幂等性具备幂等性,多次重复请求结果一致不保证幂等性,多次提交可能产生多条数据数据查询用 GET,表单提交、发布内容必须控制 POST 重复请求
安全性较低,参数明文暴露在地址栏相对更高,数据在请求体中传输,不易被直接抓取账号、密码、隐私数据禁止使用 GET 传参

1.2 幂等性概念与爬虫应用

幂等性是 HTTP 协议中的重要概念:同一个请求执行一次与执行多次,服务器产生的效果完全相同。 GET 请求仅用于查询数据,不会修改服务器资源,因此天然具备幂等性,重复请求不会产生副作用。例如多次刷新新闻列表页,页面内容不会发生变化。

POST 请求多用于新增、修改服务器数据,不具备幂等性。例如提交评论、注册账号、发布动态,重复发送 POST 请求会生成多条重复数据,甚至触发平台风控。在爬虫开发中,针对 POST 提交场景,必须增加请求去重、频率限制,规避重复提交问题。

1.3 场景选型原则

结合爬虫业务,制定标准化选型规则:

  1. 查询、获取、浏览数据,不向服务器提交任何新增内容,选择 GET 请求;
  2. 登录、注册、表单提交、发布内容、上传文件、提交接口数据,选择 POST 请求;
  3. 参数数量多、数据长度大、包含中文 / 特殊字符,优先选择 POST;
  4. 传输账号、密码、手机号等隐私信息,严禁使用 GET 请求

二、GET 请求补充拓展(进阶用法)

上一章节讲解了 GET 基础用法,本节针对实际开发中的高频进阶场景进行补充,包括 URL 编码处理、重定向控制、请求层级参数等内容,完善 GET 请求知识体系。

2.1 手动控制重定向行为

requests 库中 GET 请求默认自动跟随 3xx 重定向,部分场景下需要关闭自动跳转,直接获取重定向状态码与原始响应,例如判断页面是否失效、检测域名跳转关系。通过allow_redirects参数控制重定向开关。

代码示例

python

运行

import requests # 目标地址会触发临时重定向 url = "https://httpbin.org/redirect/2" # 关闭自动重定向 resp = requests.get(url, allow_redirects=False, timeout=5) print("状态码:", resp.status_code) print("响应头 Location(跳转地址):", resp.headers.get("Location"))
原理说明
  1. allow_redirects=False表示禁止库自动跳转,程序接收到 301/302 状态码后直接返回响应,不会继续访问新地址;
  2. 重定向目标地址会存放在响应头Location字段中,开发者可手动解析该地址完成二次请求;
  3. 该用法常用于站点状态检测、恶意链接识别、跳转链路分析等爬虫辅助场景。

2.2 长参数与特殊字符自动编码

当 GET 参数包含中文、空格、#、&、= 等特殊字符时,手动拼接 URL 极易出现解析错误。而 requests 的params参数会自动完成 URL 编码,这也是行业内统一推荐的传参方式。

代码示例

python

运行

import requests url = "https://httpbin.org/get" # 包含中文、空格、特殊符号的参数 params = { "title": "Python 爬虫&实战教程", "content": "字符测试 # @ !" } resp = requests.get(url, params=params, timeout=5) print("编码后的完整URL:", resp.url) print("服务器接收的参数:", resp.text)
原理说明
  1. URL 标准规定地址栏内不允许直接出现中文、特殊符号,必须转换为百分号编码格式;
  2. requests 内部集成 URL 编码算法,传入字典参数后自动完成转义,无需开发者手动调用编码函数;
  3. 禁止使用字符串拼接方式组装带特殊字符的 GET 参数,会大幅提升请求失败概率。

三、POST 请求基础语法与分类

POST 请求的核心方法为requests.post(),语法结构与get()类似,但新增了多种数据提交参数。根据服务器接收数据的格式,主流分为三大类:表单格式 POST、JSON 格式 POST、文件上传 POST,这也是爬虫开发中最核心的三种 POST 场景。

3.1 POST 通用语法结构

python

运行

requests.post(url, data=None, json=None, files=None, headers=None, timeout=None, allow_redirects=True)

核心参数释义:

  1. url:目标请求地址,必填项;
  2. data:用于提交表单格式数据,接收字典、元组、字符串类型;
  3. json:用于提交JSON 格式数据,接收字典类型,自动设置对应请求头;
  4. files:用于上传文件,接收文件对象组成的字典;
  5. 其余headerstimeoutallow_redirects等参数用法与 GET 请求完全一致。

3.2 表单格式 POST(application/x-www-form-urlencoded)

表单提交是传统网页最常用的 POST 数据格式,也是早期网站登录、表单提交的主流方式。请求头中Content-Type默认值为application/x-www-form-urlencoded,数据以键=值&键=值的格式存放在请求体中。

在 requests 中,使用data 参数传递表单数据,传入 Python 字典即可。

3.2.1 基础表单提交实战

python

运行

import requests url = "https://httpbin.org/post" # 表单数据,字典格式 form_data = { "username": "spider_user", "password": "123456abc", "submit": "登录" } # 使用 data 参数提交表单 resp = requests.post(url, data=form_data, timeout=5) print("响应状态码:", resp.status_code) print("服务器接收的表单数据:", resp.text)
原理说明
  1. 代码中字典form_data会被 requests 自动转换为username=spider_user&password=123456abc&submit=登录字符串,放入请求体;
  2. 库自动添加请求头Content-Type: application/x-www-form-urlencoded,适配传统表单接口;
  3. 该方式适用于绝大多数 PC 网页登录、留言提交、普通表单交互场景。
3.2.2 一维多值表单提交

部分网页表单支持一个字段对应多个值(如多选框、标签选择),此时可将字典的值设置为列表,requests 会自动解析为多组同名参数。

python

运行

import requests url = "https://httpbin.org/post" # 单个字段对应多个值 form_data = { "hobby": ["阅读", "编程", "运动"] } resp = requests.post(url, data=form_data) print(resp.text)

3.3 JSON 格式 POST(application/json)

随着前后端分离架构、移动端接口普及,JSON 格式已经成为现代接口的主流数据交互格式。移动端 APP、小程序、新版网站接口几乎全部使用 JSON 传参,这类接口必须使用json参数提交数据。

使用json参数时,requests 会自动完成两项工作:一是将字典转为标准 JSON 字符串放入请求体;二是自动设置请求头Content-Type: application/json,无需手动配置。

3.3.1 基础 JSON 数据提交

python

运行

import requests url = "https://httpbin.org/post" # JSON 格式数据,使用字典定义 json_data = { "uid": 10086, "nickname": "爬虫开发者", "info": { "level": "高级", "skill": "Python" } } # 使用 json 参数提交数据 resp = requests.post(url, json=json_data, timeout=5) print("JSON 接口响应:", resp.text)
原理说明
  1. 字典类型的json_data会被内部序列化为标准 JSON 字符串,支持多层嵌套结构,适配复杂接口参数;
  2. 自动补充 JSON 专属请求头,这是区分表单 POST 与 JSON POST 的核心标识;
  3. 移动端爬虫、小程序接口、前后端分离项目爬虫,优先使用该方式。
3.3.4 data 与 json 参数混用误区

严禁同时使用 data 和 json 参数,二者作用互斥。若同时传入,仅json参数生效,data 数据会被丢弃,导致请求参数缺失,这是新手高频错误。

3.4 文件上传 POST(multipart/form-data)

网页文件上传、图片提交、附件上传场景,会使用multipart/form-data格式的 POST 请求,该格式专门用于传输二进制文件 + 表单混合数据,在 requests 中通过files参数实现。

3.4.1 单文件上传实战

python

运行

import requests url = "https://httpbin.org/post" # 以二进制读取本地文件 file_path = "test.jpg" # files 字典:键为表单字段名,值为(文件名, 文件对象, 文件类型) files = { "upload_file": (file_path, open(file_path, "rb"), "image/jpeg") } resp = requests.post(url, files=files, timeout=10) print("文件上传响应:", resp.text)
原理说明
  1. 文件必须以二进制只读模式 rb打开,文本模式会造成文件损坏;
  2. files参数的字典结构为固定格式,依次定义表单字段、文件名、文件 MIME 类型;
  3. 库自动设置Content-Type: multipart/form-data,按照文件传输协议拆分数据包完成上传。
3.4.2 文件 + 普通表单混合提交

实际场景中,上传文件的同时往往需要附带账号、描述等表单数据,可同时搭配data参数使用:

python

运行

import requests url = "https://httpbin.org/post" # 普通表单数据 form_data = {"desc": "爬虫上传的测试图片"} # 文件数据 files = {"img": ("test.png", open("test.png", "rb"))} # 同时提交表单与文件 resp = requests.post(url, data=form_data, files=files) print(resp.text)

四、POST 请求进阶配置

本节讲解 POST 请求的通用进阶配置,包括手动设置请求头、HTTPS 证书忽略、超时与异常处理、会话保持等内容,适配复杂线上站点。

4.1 手动指定请求头

部分接口会校验请求头信息,默认请求头会被服务器拦截,此时需要通过headers参数自定义请求头,该参数 GET/POST 请求通用。

python

运行

import requests url = "https://httpbin.org/post" # 自定义请求头 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Referer": "https://httpbin.org/" } # JSON 格式 POST + 自定义请求头 json_data = {"name": "test"} resp = requests.post(url, json=json_data, headers=headers, timeout=5) print(resp.text)

4.2 忽略 HTTPS 证书验证

部分网站使用自签名证书、过期证书,发送 POST 请求时会触发SSLError证书异常。通过verify=False关闭证书校验,该配置适用于内网站点、测试站点爬虫。

python

运行

import requests url = "https://httpbin.org/post" data = {"key": "value"} # verify=False 关闭 HTTPS 证书验证 resp = requests.post(url, data=data, verify=False, timeout=5) print(resp.status_code)

补充说明:关闭证书校验后控制台会出现警告信息,可导入 urllib3 模块屏蔽警告,适配正式爬虫项目。

4.3 POST 请求异常捕获模板

POST 请求网络异常类型与 GET 一致,结合请求状态码校验、异常捕获编写通用模板,适用于所有 POST 场景:

python

运行

import requests from requests.exceptions import RequestException url = "https://httpbin.org/post" json_data = {"username": "demo"} try: resp = requests.post(url, json=json_data, timeout=6) # 主动抛出 4xx/5xx 异常 resp.raise_for_status() print("请求成功:", resp.text) except RequestException as e: print("POST 请求异常:", str(e))

五、Session 会话下的 POST 请求(登录态保持)

登录是爬虫最典型的 POST 应用场景:首先发送 POST 登录请求提交账号密码,服务器返回 Cookie,后续页面访问携带该 Cookie 即可维持登录状态。结合上一章节的 Session 会话对象,可自动保存并传递 Cookie,实现一站式登录爬虫。

5.1 模拟账号登录完整案例

python

运行

import requests # 创建会话对象,自动管理 Cookie session = requests.Session() # 1. 第一步:POST 登录请求 login_url = "https://httpbin.org/post" login_data = { "username": "spider001", "password": "666888" } # 提交登录表单 login_resp = session.post(login_url, data=login_data, timeout=5) print("登录请求响应:", login_resp.text) # 2. 第二步:使用同一会话访问需要登录的页面,自动携带 Cookie page_url = "https://httpbin.org/cookies" page_resp = session.get(page_url) print("登录后页面 Cookie:", page_resp.text) # 关闭会话 session.close()
原理说明
  1. 登录操作本质是向服务器提交身份信息的 POST 请求,验证通过后服务器下发身份 Cookie;
  2. Session 对象自动保存登录返回的 Cookie,后续同一会话内的所有请求都会自动携带;
  3. 该案例完全还原了网页登录、浏览个人中心的完整流程,是登录类爬虫的标准写法。

六、GET 与 POST 混合实战综合案例

本案例模拟真实网站查询(GET)+ 提交数据(POST)的混合业务流程,整合本章及上一章节全部知识点,实现完整业务链路爬虫。

6.1 业务逻辑

  1. 使用 GET 请求携带参数查询列表数据;
  2. 使用 Session 保持会话;
  3. 使用 POST 请求提交评论数据;
  4. 增加超时、异常捕获、请求头伪装,保证程序健壮性。

6.2 完整代码实现

python

运行

import requests from requests.exceptions import RequestException # 全局配置 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } base_session = requests.Session() base_session.headers = headers base_session.timeout = 8 # 第一步:GET 请求查询内容列表 query_url = "https://httpbin.org/get" query_params = { "page": 1, "type": "article" } try: print("===== 发起GET查询请求 =====") get_resp = base_session.get(query_url, params=query_params) get_resp.raise_for_status() print("查询结果:", get_resp.text) except RequestException as e: print("查询失败:", e) # 第二步:POST 请求提交评论 post_url = "https://httpbin.org/post" comment_data = { "article_id": 1001, "content": "通过爬虫模拟提交评论" } try: print("\n===== 发起POST提交请求 =====") post_resp = base_session.post(post_url, data=comment_data) post_resp.raise_for_status() print("提交结果:", post_resp.text) except RequestException as e: print("提交失败:", e) # 释放资源 base_session.close() print("\n全流程执行完毕")
案例总结
  1. 会话对象统一管理请求头、超时时间,减少重复代码;
  2. 查询操作使用 GET,数据提交使用 POST,严格遵循协议规范;
  3. 全流程增加异常捕获,保证爬虫连续运行;
  4. 该案例可直接改造应用于资讯网站、论坛、社区类爬虫项目。

七、常见问题与排错方案

7.1 POST 参数提交后服务器接收为空

故障现象:代码正常运行,状态码 200,但服务器未获取到提交的数据。原因与解决方案

  1. 参数格式不匹配:接口要求 JSON 格式却使用 data 传参,改为json参数;接口要求表单格式却使用 json 传参,改为data参数;
  2. 请求头缺失:部分接口强制校验Content-Type,手动补充对应请求头;
  3. 参数字段名错误:核对网页抓包结果,保证字典键名与网站原始参数完全一致。

7.2 登录 POST 请求返回 403 拒绝访问

故障现象:账号密码无误,但登录请求被拦截。原因与解决方案:缺少请求头伪装、缺少 Referer 字段、未携带前置 Cookie。解决方案:抓包浏览器完整请求头,复刻至代码中,使用 Session 完成前置请求。

7.3 GET 参数中文乱码

故障现象:URL 中中文参数解析异常,服务器识别为乱码。原因与解决方案:禁止手动拼接 URL 字符串,统一使用params字典传参,依靠库自动编码。

http://www.zskr.cn/news/1505605.html

相关文章:

  • 深入解析NXP PCA9629A步进电机控制器:I2C接口与斜坡控制实战
  • 5分钟掌握layerdivider:从单图到多层的智能图像分层技术深度解析
  • 别再死磕传统成像了!用MATLAB从零复现鬼成像(附GI、DGI、NGI完整代码)
  • 2026国内广东歌东莞表面处理化学品、塑料改性添加剂厂家首选东莞硕美 - 变量人生001
  • 榔行业迎来“升级换代”,五大品牌盘点:哪个最值得创业者押注? - 品牌官
  • UVa 458 The Decoder
  • 收藏!AI时代程序员/小白的职业护城河在哪里?通才+AI底座是关键!
  • OpenWrt 系统核心配置文件路径全解析:从无线网络到硬件驱动的默认设置
  • 2026年6月常州名表回收机构分级测评:五家平台综合评分参考 - 奢侈品交易观察员
  • 财务报销发票与差旅申请单如何自动比对?2026来也ADP解决方案
  • MPC8260A时钟配置与引脚设计:嵌入式硬件工程师的实战指南
  • 接入 Qwen2.5-VL,基于显式空间关系图的 VLM 空间推理诊断实验
  • 5分钟终极指南:零代码改造Office界面,打造专属办公神器!
  • 从攻击者视角看Nginx:手把手用Burp Suite调试CVE-2013-4547文件名逻辑漏洞
  • 从固件到应用:SMBIOS数据在现代系统中的流转与实战解析
  • Halcon实战:用最小外接矩形和正矩形精准框选瑕疵(附完整代码与效果对比)
  • 2026年安徽省亳州初中生异地择校,公办安徽建工技师学院学费全免,名额可登记 - cc江江
  • 2026青岛迪奥包包回收实测,避坑指南、本地门店横评 - 奢侈品回收测评
  • RevokeMsgPatcher深度解析:基于内存补丁的企业级消息防撤回技术实现
  • AI搜索优化公司哪家专业?2026真实测评3家主流服务商 - 资讯速览
  • 163MusicLyrics:5分钟掌握免费歌词下载与管理的完整指南
  • DataV:30分钟构建企业级数据大屏的革命性可视化解决方案
  • 郑州名表差价怎么选?禹竞标准更合理 - 禹竞
  • 零基础学STK中文实操包:8本PDF教材+Word分步指南+配套示例与开发文档
  • 告别水准仪!用Sentinel-1数据和时序InSAR,我如何在家监测城市地面沉降(附完整Python代码)
  • AGI 时代的经济结构演进:关系型部门价值、资本扩张逻辑与转型路径研判
  • 深度学习木马攻击原理与防御技术详解
  • 如何彻底解决显卡驱动问题:专业免费工具的终极指南
  • Demucs 6秒音频分离:终极快速免费音乐源分离工具
  • 深入解析OL2381射频收发器:工作模式切换与PLL启动流程