长连接 在发post请求时,长连接这个不用带上,一般带上User-Agent、Referer、Content-Type这些就行了,提交不成功再看有没有其他什么特殊的协议头需要带上。
菜鸟教程:https://www.runoob.com/http/http-intro.html
统一资源定位符:URL就是抓包抓到的链接地址,你怎么叫它都行
比如下面这一坨就是我百度搜索刘德华时抓包抓到的URL
https://www.baidu.com/s?ie=utf-8&mod=1&isbd=1&isid=9b2a476a00063f34&ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%88%98%E5%BE%B7%E5%8D%8E&fenlei=256&oq=%25E5%2588%2598%25E5%25BE%25B7%25E5%258D%258E&rsv_pq=9b2a476a00063f34&rsv_t=8534esFPC91%2B1%2BkCH9Bpe%2Fo6lvZEa88SciF5TR9GNjkRclELTP2gPbx%2Fzys&rqlang=cn&rsv_enter=0&rsv_dl=ts_1&rsv_btype=t&prefixsug=%25E5%2588%2598%25E5%25BE%25B7%25E5%258D%258E&rsp=1&rsv_sug9=es_0_1&rsv_sug=2&bs=%E5%88%98%E5%BE%B7%E5%8D%8E&rsv_sid=7560_32606_1436_31660_32045_32681_32115_31321_32691_26350_22157&_ss=1&clist=dd522d4d380e9b8c&hsug=&f4s=1&csor=3&_cr1=40768
这么一坨看起来很乱,其实URL的结构很简单
协议://域名或IP地址:端口/路径?参数1=值&参数2=值 … 一般端口是省略的,HTTP默认端是80,HTTPS是443,这些是约定成俗的,所以可以省略,假如你的网站端口是其他 如:233,那么访问你的网站的时候是要带上端口的:协议://域名或IP地址:233 结构: https://www.baidu.com:443/images/demo.jpg https:使用https协议 www.baidu.com:域名 443:端口 可省略,https默认443端口 images:域名指向的服务器目录下的一个目录 demo.jpg:目录下的一个文件 https://www.baidu.com/images/login.php?user=123&pass=456 login.php:登录网页 目录下的一个文件 ?:用于隔开网页文件名与提交的参数 user=123:GET方式向服务器发送一个参数user,值为123 &:连接下一个参数
关于URL的巴拉巴拉介绍
在WWW上,每一信息资源都有统一的且在网上唯一的地址,该地址就叫URL(Uniform Resource Locator,统一资源定位器),它是WWW的统一资源定位标志,就是指网络地址 URL由三部分组成:资源类型、存放资源的主机域名、资源文件名 也可认为由4部分组成:协议、主机、端口、路径 URL的一般语法格式如下:(带方括号[]的为可选项) protocol://hostname[:port]/path/[;parameters][?query]#fragment protocol(协议):最常用的是http、https协议;file是本地计算机上的文件,格式:file:///,注意后边应是三个斜杠,ftp是通过 FTP访问资源 hostname(主机名):简单理解为域名或IP地址 port(端口号):http默认80端口、https默认443 path(路径):域名指向服务器目录下的目录/文件地址,由零或多个"/"符号隔开的字符串,就是你访问的这个文件在网站服务器的位置(比如:某个目录下的某个目录下的某个文件:a/b/c.txt) parameters(参数):用于指定特殊参数的 query(查询):就是链接上的参数,可有多个,用“&”符号隔开,每个参数的名和值用“=”符号隔开 fragment(信息片断):用来定位网页上的字符片段的,比如你在阅读我这篇文章的时候,点击文章目录可以快速定位到指定的位置,就是用的这个玩意
好像也没啥好介绍的,做没做过网站的都知道这些,还有就是绝对路径和相对路径,这些百度一下知道了
URL编码是专门针对URL和post参数的,有些网站、有些类型的post参数不需要编码,具体抓个包就知道了
一些中文和特殊符号要进行URL编码,方便数据传输,因为URL有硬性规定,只允许大小写英文、数字和指定的一些符号,所以在我们提交请求的时候也要对构造的数据进行编码,纯英文数字、和一些特定的符号不用编码,比如一个域名:https://www.baidu.com/,肯定不用编码,但是一个邮箱:123456@qq.com,因为有@这个字符,所以要编码
像这种很多%的就是URL编码:
%E5%88%98%E5%BE%B7%E5%8D%8E 一般抓包抓下来的原始数据只要含有中文或特殊符号都是进行编后的,都会编码成这种带%的字符 URL编码一般分为gbk和utf-8两种,用编码工具或者代码对抓下来的包进行URL解码,测试一下就知道到底是哪种编码了,如果不乱码就是正确的
解码后不乱码,出现正确的内容,表示你使用了正确的解码方式
URL解码后:刘德华
URL编码中的加号和空格
大概知道有这么回事就行了,+号和空格在编码的时候经常会遇到这种问题,如果实在没招了,就用笨办法,直接把+号或者空格替换成其编码后的字符,空格是:%20,+号是:%2B
协议头好像没啥好说的 直接上小肩膀post+js第三期视频里讲的例子,当年我学习的时候截的图
下图中,VerificationToken不是常规请求头,是服务器自己构造的,用来判断是否访问过某个页面的,其值是在那个页面中获取到的
协议头可以自定义,有些网站会在协议头里传递重要数据,这些特殊的协议头一般都是需要的,有的是前面页面返回的,有的是加密的 需要找到对应的加密算法
常见状态码:200 302 404
菜鸟教程:https://www.runoob.com/http/http-intro.html
在post请求的协议头中,Content-Type也是很重要的,用来指定提交参数的类型
常见的有下面三种
这里要说的编码和URL编码不太一样,一般在post的时,需要对网页返回的数据进行编码转换
查看网页是什么编码
右键查看源代码,可以看到:
<meta charset="utf-8"> utf-8编码 <meta charset="gbk"> gbk编码 一般程序员在开发网站的时候都会在头部写上这一句html,是为了告诉浏览器以何种方式解析文档 真正决定网页编码的是在文件保存的时候,也就是程序员在保存代码的时候要和他指定的一致 并且网站里所有相关的编码都以这种方式编码,大概是这个意思易语言中经常遇到的编码
gbk、gb2312、ansi、utf-8 … 编码不对是中文乱码的根源,也是导致提交数据出错的重要原因:由于易语言是gbk编码的,而大多数网站是utf-8编码的,所以在post请求时经常会遇到的编码问题 U码:\u6ce8\u518c\u6210\u529f,这玩意在一些请求返回数据中经常出现 十六进制转义文本:65797579616e => \x65\×79\x75\×79\×61\x6e(js混淆中会遇到) 十六进制前面都加上了\x(转义)JS混淆会遇到这种东西,Python中的字节就是以这种方式表示的
编码到底怎么来的,为什么要有编码这么个变态的东西,具体看下面两篇文章就知道了
编码发展史:https://blog.csdn.net/dk_0520/article/details/70157426
ansi、gb2312、unicode与utf-8编码的区别:https://blog.csdn.net/chruan/article/details/8812110
任何数据都能被编码为只用65个字符表示的文本
A~Za-z0-9+/=
常用于:密钥、密文、图片、普通数据
易语言的Base64编码/解码与浏览器中的btoa/atob执行结果一样
大多数Base64编码后结果都是一样的,也有其他例外(Base64有多种,常规的内部实现的算法都是一样的,进行过变形/修改的就不一样了)
302跳转的包,使用网页_访问_对象时,需要把禁止重定向设置为真,这个时候才可以操作cookie、协议头等一些信息
在返回协议头放一个变量,取出里面的location,得到要跳转的地址,访问此地址时提交cookie用302那个包返回的(一般情况下,和平时一样就行了,都是提交cookie的那个变量),也就是把302跳转手动分成两个包提交了
用网页访问S,直接在返回重定向那里给个变量就可以获取到要跳转的地址了
其他语言都一样,用相应的命令就完事了
1、cookie的分类
服务器返回:set-cookie JavaScript生成2、cookie的作用
识别身份证(图片验证码、短信验证码) 判断是否访问过某些请求(一些看似无意义的关键请求) 判断是否登录状态(网站发帖、评论、改个人资料等各种操作)3、cookie的结构
cookie的话,大多数编程语言都可以自动处理,手动获取再合并更新太麻烦了 比如Python的requests库,设置保持cookie后,之后的操作跟浏览器一样,都会自动合并更新cookie的 易语言的话,一般大多数的网页_访问_对象()命令,只要在提交cookie那里给一个变量,每次请求完成后,这个变量的值都是合并更新后的cookie,所有的请求都在提交cookie那里加上这个变量,就是保持cookie了 而返回cookie那里一般什么都不要放,因为模块在每次请求前都会清空返回cookie这个变量,如果你在提交cookie和返回cookie里都放了同一个变量,那么你前面所有的操作有可能都白费了 取出某个请求返回的cookie: 1、直接用提交cookie那里的变量:新建一个变量把提交cookie赋值给这个变量,这样防止一些操作会影响到提交cookie里的值 2、新建一个变量,放到返回cookie那里 这两个方法返回的结果可能会不一样,具体看情况而定,只有能达到想要的结果就行
上面说的保持cookie什么的,是模块/库实现的,所以你要看你用的模块/库是怎么写的、具体是怎么处理cookie的、支不支持才行
注意:
抓包前,一定要清除浏览器cookie,否则有些包可能会抓不到,或者抓到的包不正确,因为浏览器中有缓存cookie
在响应头中的set-cookie就是服务器返回的cookie,这些cookie会被浏览器记录下来,而我们用代码写post的时候就是在模拟这些操作
比如下面这一坨,就是从响应头里复制的cookie:
set-cookie: sid_guard=5c9ec4231ba959bfd3c0e52d1130c17b%7C1599134091%7C5184000%7CMon%2C+02-Nov-2020+11%3A54%3A51+GMT; Path=/; Domain=toutiao.com; Max-Age=31104000; HttpOnly set-cookie: uid_tt=b64ad76eeb3d0730620c7101ab44582b; Path=/; Domain=toutiao.com; Max-Age=5184000; HttpOnly set-cookie: uid_tt_ss=b64ad76eeb3d0730620c7101ab44582b; Path=/; Domain=toutiao.com; Max-Age=5184000; HttpOnly; Secure; SameSite=None set-cookie: sid_tt=5c9ec4231ba959bfd3c0e52d1130c17b; Path=/; Domain=toutiao.com; Max-Age=5184000; HttpOnly set-cookie: sessionid=5c9ec4231ba959bfd3c0e52d1130c17b; Path=/; Domain=toutiao.com; Max-Age=5184000; HttpOnly set-cookie: sessionid_ss=5c9ec4231ba959bfd3c0e52d1130c17b; Path=/; Domain=toutiao.com; Max-Age=5184000; HttpOnly; Secure; SameSite=None 前面一段是cookie信息,后面是cookie多久后失效什么的 一般在处理cookie的时候,后面是不要的,只取到第一个分号那里 然后进行合并处理,处理后作为下一次请求时的请求cookie比如说我们登陆一个论坛网站,在登陆前,我们是没有cookie的,因此访问这个网站的时候都是未登录状态,不可以做任何评论、发帖子这些操作,当提交登陆后,如果登陆成功,服务器会返回一些cookie给我们,这就是响应头里的set-cookie,这些cookie被浏览器记录下来了
之后再访问这个网站的时候,就会把这些cookie整理合并更新,提交给服务器,服务器判断你是不是已登陆用户,这就是post提交数据时用到的提交cookie
比如下面这一坨,就是从请求头里复制的cookie:
cookie: __ac_signature=_02B4Z6wo00f019njazQAAIBBmh1hmzIq4N.Z42-AAKky5d; ttcid=401d943fd06f422d997203f793699b8313; csrftoken=0625180db5f92d13d5903c5144df46f2; tt_webid=6868228216486774280; MONITOR_WEB_ID=8336cbdd-571b-4194-8048-89e4d3b4c850; s_v_web_id=verify_kemr3q1g_eESPlDag_NRYi_4Sbk_8VlD_SULnDxjEiF34; WEATHER_CITY=%E5%8C%97%E4%BA%AC; tt_webid=6868228216486774280; tt_scid=zJ9DfZlXWZk8As91.bptbTKx1WRGJiHmM1fNSCD4Yb4YCLxpxUasWGE7q47gf3xUad19; __tasessionId=hnqiss7uj1599134016286; passport_csrf_token=476c0864fd832c821d2859145ff5c0e9; passport_auth_status=229b5e43d50f88c6962341baa6d46d40%2C; sso_auth_status=2017f6dd31daf868e5029aa9114c482f; sso_uid_tt=2933825728f829695b8342f35ffa5c39; sso_uid_tt_ss=2933825728f829695b8342f35ffa5c39; toutiao_sso_user=51403359b0cfb44cf3c5d7857692c505; toutiao_sso_user_ss=51403359b0cfb44cf3c5d7857692c505有了这条cookie,之后我做任何操作都是带上这条cookie的,服务器就知道这是已经登陆后的我,浏览器会把新的cookie和我之前的cookie进行合并更新,每次都是提交合并更新后最新的cookie
所谓的合并更新:
每一段cookie的格式:名字=值 当我发送一次请求时,假如服务器返回新的cookie了,首先对新cookie进行过滤,过滤掉一些无效的字段,然后分割每一段旧cookie、遍历,根据名字在新cookie里找每一段旧cookie,如果新cookie里有旧cookie同名的就把旧的丢掉,最后处理一下剩下的旧cookie,追加到新的里,产生一个新的cookie,大概就是这个意思
伪装IP现在基本上没有什么卵用了,一般都是用代理IP和拨号换IP了
直接在协议头上加上下面这些字段就行了,你可以都加上,也可以看哪个顺眼加哪个,然后随机生成IP地址,替换掉[IP地址],具体原理百度上很多解释的,我就不巴拉巴拉了
X-Forwarded-For: [IP地址] CLIENT_IP: [IP地址] VIA: [IP地址] REMOTE_ADDR: [IP地址] X-Real-IP: [IP地址]
大概意思就是告诉服务器:唉,快看!这是我的IP地址
这个时候服务器会回复你:滚,我又不傻
写代码基本流程
1、接收响应头set-cookie 2、找齐参数,构建关键封包,附加请求头 3、判断是否成功 有JS生成cookie的情况比较麻烦,最后考虑代码纠错技巧
比较容易出错的地方 1、提交的数据该编码的没有编码 (有些二次编码) 2、提交的数据不该写死的写死了 3、替换数据的时候不够仔细 4、忽略了一些看似没用的关键请求 5、延迟 基本纠错技巧 1、关键变量调试输出 2、断点调试 3、对自己的程序进行抓包 对比网页上的