http协议学习 —— post请求方法提交application/x-www-form-urlencoded类型的数据格式
2020-03-23 13:48:52 更新:
最近看到部分文章阅读量竟然变高了,有点惶恐,希望自己不会误人子弟。这篇文章是非常浅显的 http 协议的一小部分,如果要全面了解 http / 1.1 协议,请移步:RFC 7231
它是http 1.1 标准规范档案,里面讲述十分详细。(我记得火狐开发者社区也有)
比如 http1.1 Accept-Encoding 字段中描述了如何压缩 body 进行传输,这点很重要,我最初自己写http客户端的时候还不知道,于是从服务器获得的 html 内容都是乱码,其实这是因为服务端将 body 部分使用 br 、gzip、deflate 等方法进行了编码。并且对其压缩算法也有较详细的描述,简单来说都是基于哈夫曼树的改进和优化(详见 RFC 1951 DEFLATE、RFC 1951 GZIP)
对各种响应状态码的解释、缓存控制、Session等。
最后,大家有没有真正的意识到一点呢,其实计算机越学越发现,基本上就是在学习前人与计算机定下的规则呀~,无论哪一个方面(硬件、语言、算法、软件、图片等),然后终将有一天,我们也开始制定一些规则,让别人参与进来。所以对各种协议、文档存储格式等有一定深入了解是非常重要的一件事。
以下为原文:
先推荐一篇很不错的文章:https://imququ.com/post/four-ways-to-post-data-in-http.html
说一下,如果是自己编写底层,那么要注意了,不能只有提交数据的类型,还必须要有数据内容的长度,大体这样写即可:
method << "POST / HTTP1/1\r\n";
headers << "Content-Length: 32\r\n";
headers << "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n";
...
body << "test=1&type=json&time=1513242234";
请求头部分结束的后面就是请求主体(body),发送的body内容是key-value对应的url source,如果带有中文或其他非英文语种,类似这样:
type=1&message=%E5%8A%A9%E6%89%8B&plat=1&jsonp=jsonp
需按url编码格式编码。注意不用在字符串尾部加"\r\n"。
实际上这种类型的提交参数实现了通过接口对服务器后台的数据库进行CRUD操作。
我之前仅仅只是会用python的requests库,没怎么了解底层,现在自己用C++写爬虫才知道,人家已经帮我们做好了这些事,十分便利,同时也看到了她的强大之处。
下面用C++测试B站的add接口(发表评论)为例:
#include <iostream>
#include <sstream>
#include "libhttp.hpp" using http::Request;
using std::string;
using std::stringstream; int main()
{
Request r; string url = "https://api.bilibili.com/x/v2/reply/add"; stringstream headers; headers << "Contention: keep-alive\r\n";
headers << "Content-Length: 102\r\n";
headers << "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n";
headers << "Cookie: xxx\r\n";
headers << "Host: api.bilibili.com\r\n";
headers << "Referer: https://www.bilibili.com/bangumi/play/ep85276\r\n";
headers << "User-agent: xxx\r\n"; string data = "oid=4492528&type=1&message=%E5%8A%A9%E6%89%8B&plat=1&jsonp=jsonp&csrf=14211ebe19f7a1500e3a4d910c9d4b44";
// decode: "oid=4492528&type=1&message=助手&plat=1&jsonp=jsonp&csrf=14211ebe19f7a1500e3a4d910c9d4b44"; r.post(url, "", headers.str(), data, ""); return 0;
}
运行结果:

到B站上看看:

测试成功,这里测试环境是Linux CentOS7。
如果使用python requests模块,可以简单这样写:
# coding=utf8
from requests import request data = {
'oid': '4492528',
'type': '1',
'message': '正片被tx抢走了',
'plat': '1',
'jsonp': 'jsonp',
'csrf': '141500e3a4d910c9d4b44'
} headers = {
'Cookie': 'xxx'
} r = request('post', 'https://api.bilibili.com/x/v2/reply/add', data=data, headers=headers, timeout=1) print r.status_code
print r.text
她的底层会根据你自定义的headers以及data进行解析,然后补充上一些缺少的重要key-value。
顺便提下之前在该篇中提到的csrf
1.旧csrf + 旧cookie:

2.新csrf + 旧cookie:

3.旧csrf + 新cookie:

# 2018-12-15 12:02:22 咳咳,今天回头看了一下这篇文章。。。はつかし。。。emmm,发现自己真是个文盲。。。基本上各大网站的csrf和cookie都是有生命周期的。。。一些网站做得更严谨,可能关闭掉网页就死了,但一般都是通过session来持续一段生命周期,并且csrf是一种名为Cross-site request forgery(跨站请求伪造)的技术,嘛,做过网站应该就明白了。所以,我重新登录,之前的csrf以及cookie当然会失效。。。
...然后B站的csrf怎么获得呢?不可能每次都发表评论 + F12看吧,这也太事后诸葛亮了,所以找找还有没有其他方法,当然我也是无意间找到一个办法,当视频播放时,有个接口会每隔几秒钟发送一次请求,其中也带有该视频下通用的csrf,这个接口名为:heartbeat,如图:

点一下她,在Headers中From Data就可以看见了。
ps:今天才知道如何查看网站的robots.txt,在浏览器地址栏中输入是格式:http://网站主页/robots.txt,比如B站的:https://www.bilibili.com/robots.txt,上面写清楚了网站中哪些是不允许爬取的。
参考:
1.https://www.zhihu.com/question/34980963
2.http://www.robotstxt.org/robotstxt.html
http协议学习 —— post请求方法提交application/x-www-form-urlencoded类型的数据格式的更多相关文章
- 标准Http协议的六种请求方法详解
标准Http协议支持六种请求方法,即: 1.GET 2.POST 3.PUT 4.Delete 5.HEAD 6.Options 但其实我们大部分情况下只用到了GET和POST.如果想设计一个符合RE ...
- python学习 —— post请求方法的应用
声明:本篇仅基于兴趣以及技术研究而对B站曾经发生过的抢楼事件背后相关技术原理进行研究而写.请不要将其作为私利而对B站以及B站用户体验造成影响!谢谢合作!若本文对B站及其用户带来困扰,请联系本人删除本文 ...
- HTTP协议的六种请求方法
抛砖引玉,聊下概念性的东西先: HTTP协议 (Hyper Text Transfer Protocol) HTTP是一个基于TCP/IP通信协议来传递数据,包括html文件.图像.结果等,即是一个客 ...
- HTTP协议简介详解 HTTP协议发展 原理 请求方法 响应状态码 请求头 请求首部 java模拟浏览器客户端服务端
协议简介 协议,自然语言里面就是契约,也是双方或者多方经过协商达成的一致意见; 契约也即类似于合同,自然有甲方123...,乙方123...,哪些能做,哪些不能做; 通信协议,也即是双方通过网络通信必 ...
- http学习--常用请求方法和响应状态码
常用的http请求方法: GET方法:请求服务器资源,并返回 POST方法:向指定资源提交数据进行处理请求(比如说表单,上传文件等).数据被包含在请求体中.POST请求可能会导致新的资源建立或已有资源 ...
- HTTP协议、HTTP请求方法、常见状态码、HTTP消息
HTTP协议 客户端请求,服务端响应.浏览器与服务器不建立持久连接,响应后连接失效. HTTP请求方法 一.GET GET方法用于获取请求页面的指定信息. 二.HEAD 除了服务器不能在响应里返回消息 ...
- SpringMVC 学习笔记(请求方法的返回值和参数)
在用注解对配置 处理器时,一般是一个方法处理一个请求,不同方法的返回类型有着不同的意义. 返回值为 ModelAndView 类型 ModelAndView 是Model 和 View 的一个集合类型 ...
- php模拟HTTP协议发送post请求方法
今天用到php模拟http发送post请求记录 代码如下: <?php $url = 'xxxx.com'; $data = 'a=one&b=two'; $data = urlenco ...
- HTTP协议中POST、GET、HEAD、PUT等请求方法以及一些常见错误
(来源:http://www.tuicool.com/articles/Ermmmyn) HTTP请求方法: 常用方法: Get\Post\Head (1)Get方法. 取回请求URL标志的任何信息, ...
随机推荐
- ES5中, map 和 forEach的区别
forEach和map区别在哪里知道吗? // forEach Array.prototype.forEach(callback(item, index, thisArr), thisArg) // ...
- 浅谈对Jquery+JSON+WebService的使用小结
https://www.jb51.net/article/36207.htm 更新时间:2013年04月28日 12:19:55 作者: 我要评论 本篇文章介绍了对Jquery+JSO ...
- Educational Codeforces Round 81 (Rated for Div. 2)E(线段树)
预处理把左集划分为大小为1~i-1时,把全部元素都移动到右集的代价,记作sum[i]. 然后枚举终态时左集的大小,更新把元素i 留在/移动到 左集的代价. 树状数组/线段树处理区间修改/区间查询 #d ...
- 排序算法之归并排序的python实现
采用分治法: 分割:递归地把当前序列平均分割成两半. 集成:在保持元素顺序的同时将上一步得到的子序列集成到一起(归并). 归并操作(归并算法),指的是将两个已经排序的序列合并成一个序列的操作.归并排序 ...
- Hyperledger Explorer
简介 Hyperledger Explorer is a simple, powerful, easy-to-use, well maintained, open source utility to ...
- Java Interview Questions Summary
Spring 高并发 Java基础 多线程 正文. 多线程精选53题 1.什么是线程 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器 ...
- android实现扫一扫等功能
链接:https://blog.csdn.net/weixin_40399313/article/details/78814325
- Leet Code 9.回文数
判断一个整数是否是回文数. 题解 普通解法:将整数转为字符串,然后对字符串做判断. ///简单粗暴,看看就行 class Solution { public boolean isPalindrome( ...
- zookeeper基本使用
(1)查看节点信息:ls / (2)查看单个节点的状态:stat /zookeeper (3)在Java中使用的zk客户端:zkClient,curator (4)curator是apache的开源的 ...
- Python 命令行参数的输入方式(使用pycharm)
形式一: 第一个红色框为命令行参数 第二个框为控制台模式(Terminal) 形式二 点击运行:点击红色框 编辑配置 如下图:红色框即为设置的命令行参数