websocket与爬虫

背景

写爬虫的目的应该就是为了拿到数据,或者说模拟某种操作
如果他使用的是http(s) 协议来传输数据的,那么我们就模拟http协议来发送数据
如果它使用的是websocket协议来传输数据的,
那么我们理所当然的就模拟websocket来发送数据~

首先,我们需要了解什么是websocket

websocket的介绍

WebSocket是一种在单个TCP连接上进行全双工通讯的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

上面是维基百科的介绍.
简单的将,websocket 和http一样,都是一种网络传输协议

他比http协议好的地址有哪些呢?

  • 较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。
  • 更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。
  • 保持连接状态。于HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
  • 更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
  • 可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
  • 更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率

websocket的应用场景

  • 直播平台的弹幕
  • 实时聊天
  • 等等

websocket 协议

WebSocket 是独立的、创建在 TCP 上的协议。

Websocket 通过 HTTP/1.1 协议的101状态码进行握手。

为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”

那么websocket协议是如何握手的呢?

websocket握手

下面是websocket一次握手的过程
客户端请求

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

服务器响应

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Location: ws://example.com/

和http字段不一样的地方

  • Connection必须设置Upgrade,表示客户端希望连接升级。
  • Upgrade字段必须设置Websocket,表示希望升级到Websocket协议。
  • Sec-WebSocket-Key是随机的字符串,服务器端会用这些数据来构造出一个SHA-1的信息摘要。把“Sec-WebSocket-Key”加上一个特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后计算SHA-1摘要,之后进行BASE-64编码,将结果做为“Sec-WebSocket-Accept”头的值,返回给客户端。如此操作,可以尽量避免普通HTTP请求被误认为Websocket协议。
  • Sec-WebSocket-Version 表示支持的Websocket版本。RFC6455要求使用的版本是13,之前草案的版本均应当弃用。
  • Origin字段是可选的,通常用来表示在浏览器中发起此Websocket连接所在的页面,类似于Referer。但是,与Referer不同的是,Origin只包含了协议和主机名称。
  • 其他一些定义在HTTP协议中的字段,如Cookie等,也可以在Websocket中使用。

可以看到只是在http协议上增加了几个硬性规定,http协议的user-agent,cookie都可以在websocket握手过程中使用

抓包时候的注意事项:因为websocket只有一次握手,握手成功后就可以双方发送消息了,假如你打开网页后没有找到你要抓的数据,那么你就需要重新刷新网页,让他重新握手一次

websocket的事件

on_open

表示刚刚连接的时候

onmessage

表示收到消息怎么做

send

表示给服务器发送消息

on_close

表示关闭连接

那么知道了这些对我们有什么好处么?
找js的时候会很好找,这几个关键词基本上都是固定的
你可以直接全局搜搜,然后很容易能找到发送的js代码

模拟发送的时候也是一样的.

实际案例

前面介绍了一堆websocket协议相关的东西,估计很多人已经晕了.
没关系,先看实例,有问题再回到上面看

抓包可以使用fiddle,chrome也是可以的

我们先使用chrome

本次要抓的网站的一个投票网站
大家可以先随便投一个票,抓抓包看看
会发现怎么没有找到他是如何提交数据的...

选择ws,然后刷新下网页,再点击下投票,会发现有一个请求


image

可以看到是在握手阶段,请求头里面的参数和我们上面讲的是一样的.

请求地址是ws://v5.10brandchina.com:8008/
这边顺带说一下,有时候这边会看到 wss://v5.10brandchina.com:8008/
那么这两个有啥区别的,简单的讲就是http与https协议的区别一样...

image

看一下交互的内容(点击Frames)
可以看到已经有四条消息了,但是消息内容是二进制的,chrome这边无法预览...
那么我们使用fiddle试一下

image

抓包与分析

打开fiddle,刷新一下网页
不刷新的话是看不到的,然后随便投一下票.

image

怎么找到请求呢,很简单,看状态码为101的就行,然后双击这一行

然后这边还是看到四条消息,我们点击第一条,然后用TextView展示,可以看到消息是这些
为啥用TextView呢?其实是一个一个的试过来的,假如你发现都试过了,还是乱码,那应该是他使用了其他的压缩或者加密方法,需要查看js看看他是如何加密的

image

这个网站的数据是没有加密过的.
带向上的箭头的是我们向服务器发送的,向下的箭头是服务器返回的(下面的数据,前面带黑点?,是我们发送的)

  • {"action":"auth","val":5}

{"action":"auth","msg":"eval(\"\\115\\141\\164\\150\\56\\163\\151\\156\\50\\61\\65\\61\\67\\67\\66\\62\\63\\61\\63\\51\")"}

  • {"action":"auth","val":-0.3241458910493796}

{"action":"wait","msg":95420}

  • {"action":"vote","val":"{\"itemid\":126067,\"catid\":41867,\"captcha\":\"%u7EC7%u65E7%u5F88%u9C7C\",\"auth\":5,\"rnd\":\"4186712606754595\"}"}

{"action":"vote","msg":"ok,231812,2018-02-04 22:32:55"}

可以看出来
首先我们发送{"action":"auth","val":5}
然后服务器返回一串信息给我们,
然后我们根据服务器返回的算出一个值,也就是
{"action":"auth","val":-0.3241458910493796}
再发送给服务器.
服务器返回{"action":"wait","msg":95420},表示验证通过
然后我们投票,发送了投票的一些信息给服务
服务器告诉我们投票成功.

以上就是整个通讯过程.

那如果我们要模拟发送的话,需要知道哪些信息呢

  1. {"action":"auth","val":5}里面的val:5,这个5是固定的么?如果不是,是如何生成的
  2. 服务器返回的是什么,如何解析
  3. 如何根据服务器返回的生成一个新的val
  4. 发送投票信息里面{"action":"vote","val":"{\"itemid\":126067,\"catid\":41867,\"captcha\":\"%u7EC7%u65E7%u5F88%u9C7C\",\"auth\":5,\"rnd\":\"4186712606754595\"}"}
    itemid,catid,capthc,auth,rnd如何生成

找参数

还是使用chrome,直接用ctrl + shift +f,然后输入websocket(或者on_open,on_message,等等上面提到的事件去搜索)

运气很好,输入websocket直接就搜到了js,还是没有混淆的

image

首先发现 websocket 地址是根据catId变的,如果catId能被2整除则地址为xxx,否则为xxx
那么catId是什么呢,调试发现就是url中的id,我们当前url为http://www.10brandchina.com/vote/startin.php?id=41867则 catId为41867

然后onmessage也看到了,大概意思是收到信息后,用json解析,如果action是auth的话,则调用sendData这个方法,如果action是vote的话,则使用vote_resule方法.

image

在看到onopen方法,是调用sendData,并发送('auth',authType),在这边是不是联想到前面,我们第一次发送的数据?{"action":"auth","val":5},是不是感觉一模一样

close方法就不说了,反正我们也用不上


image

再看看sendData这个方法,


image

用python实现的话是这样
image

再看vote_result方法,大概作用是判断投票结果


image

所有的方法我们都找到了,那么我们再和之前要找的参数走一遍.

  1. {"action":"auth","val":5}里面的val:5,这个5是固定的么?如果不是,是如何生成的

这个5也就是onopen里面的authType,至于authType是不是固定的,搜索一下就知道了.

  1. 服务器返回的是什么,如何解析
  2. 如何根据服务器返回的生成一个新的val

可以通过onmessage方法知道他返回的json数据,json解析一下就行,
里面的val是通过执行 eval(val)得到的
所以你也可以直接执行这个.或者用python实现

image

  1. 发送投票信息里面{"action":"vote","val":"{\"itemid\":126067,\"catid\":41867,\"captcha\":\"%u7EC7%u65E7%u5F88%u9C7C\",\"auth\":5,\"rnd\":\"4186712606754595\"}"}
    itemid,catid,capthc,auth,rnd如何生成

itemid 就是你投票的公司的id,catid之前讲过,captcha就是验证码,
auth和上面的authtype一样
rnd是通过搜索js发现了.

image

再看看验证码是如何生成的呢


image

检查验证码是否正确


image

我们已经拿到所有需要的东西了,只要用程序模拟发送就行了.

模拟发送

使用的包是websocket

官方demo

import websocket
try:
    import thread
except ImportError:
    import _thread as thread
import time

def on_message(ws, message):
    print(message)

def on_error(ws, error):
    print(error)

def on_close(ws):
    print("### closed ###")

def on_open(ws):
    def run(*args):
        for i in range(3):
            time.sleep(1)
            ws.send("Hello %d" % i)
        time.sleep(1)
        ws.close()
        print("thread terminating...")
    thread.start_new_thread(run, ())


if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://echo.websocket.org/",
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)
    ws.on_open = on_open
    ws.run_forever()

可以看到使用还是很简单的,也是onopen,onmessage,send

所以我们只要用我们上面得到的信息就行模拟发送就可以了

因为是投票网站,所以不提供代码...有啥问题,请留言~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • 我们用websocket和http来研究一下TCP/IP协议的一些特性,在上一篇文章《https连接的前几毫秒发生...
    极乐君阅读 1,915评论 1 6
  • 都说90后是互联网的原住民,我比较特殊,由于自制力好、比较听话,所以,直到大学才真正遇到了互联网。 小学——200...
    charmingspring阅读 458评论 1 48
  • 我的男神住在我的对门,我有一个不光明的癖好,就是我每天都会躲在自家门缝后面偷看他回来。 我没有和他说过一句话,因为...
    四夏仙影阅读 673评论 4 2
  • 第34章 众神科技与地球人 “你说什么?地球人?”我控制不住自己的情绪,声音也提高了许多。 “你这么大声干嘛啊?你...
    图七上层阅读 340评论 2 8