http协议学习 —— post请求方法提交application/x-www-form-urlencoded类型的数据格式

  先推荐一篇很不错的文章: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";

  然后再在请求头部分结束的后面加上key-value对应的url source,注意不用在尾部加"\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";// "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,这次做了一些有意义的测试,获得了一点有用的信息,貌似B站的csrf(校验)在不同的电脑操作系统、浏览器下是不一样的,它们有自己的csrf,比如我Windows 10 + Chrome 时是dxxx,使用CentOS7 + Chrome时是1xxx。

  我在思考,这里公开这个csrf校验码安全吗?还有以前写的爬虫代码中貌似有一些公开的Cookie,很不安全阿,比如B站的这个add接口,虽然不知道csrf是否与Cookie有绑定进行验证,但假如两个没有太大关系的话,csrf使用自己浏览器上显示的,请求头只用加上别人的Cooike就可以随意代表Cookie对应的用户发表评论了,可以想到如果公开Cookie的话,一些坏人利用这个Cookie到处为非作歹怎么办?以前安全意识太差了。。。也在这里提醒大家,不要因为学习而忽略掉这样的安全问题,我觉得至少Cookie不能公开。

  ...然后csrf怎么获得呢?不可能每次都发表评论 + F12看吧,这也太事后诸葛亮了,所以找找还有没有其他方法,当然我也是无意间找到一个办法,当视频播放时,有个接口会每隔几秒钟发送一次请求,其中也带有该视频下通用的csrf,这个接口名为:heartbeat,如图:

  点一下她,在Headers中From Data就可以看见了。

  今天才知道如何查看网站的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

猜你喜欢

转载自www.cnblogs.com/darkchii/p/9070175.html
今日推荐