chrome headless 爬虫抓取websoket 数据

栏目: Html5 · 发布时间: 6年前

内容简介:数据一直在不停的闪,直觉判断这种高频的显示应该不会用ajax 轮询的方式,至少也是websocket的方式直接看到,右边正边疯狂的刷新数据,而使用的协议,正是websocket ,对于python下如何连接websocket ,网上有很多的文章,我这里就不用细说了,通常我们拿到这样的接口,都会本能去尝试直连看看,在进一步尝试之后,发现他们的api应该有一种特别的方式(又或者我的代码有写错的地方)在运行程序之后毫无效果,另外端口的api会根据真实的请求变化 ,而且进一步的请求的cookie和key都会变化

目录

  • 源起
  • 分析
  • 实践
  • 总结

源起

周末答应了一个朋友帮他看一下一个网站应该怎么爬,费话不说直接先上网站

https://datacenter.jin10.com/price

chrome headless 爬虫抓取websoket 数据

数据一直在不停的闪,直觉判断这种高频的显示应该不会用ajax 轮询的方式,至少也是websocket的方式

分析

老规矩,直接上chrome 的f12来分析看看

chrome headless 爬虫抓取websoket 数据

直接看到,右边正边疯狂的刷新数据,而使用的协议,正是websocket ,对于 python 下如何连接websocket ,网上有很多的文章,我这里就不用细说了,通常我们拿到这样的接口,都会本能去尝试直连看看,在进一步尝试之后,发现他们的api应该有一种特别的方式(又或者我的代码有写错的地方)

# coding:utf-8
 
from websocket import create_connection
from websocket import ABNF
 
api = "wss://sshibikfdn.jin10.com:9084/socket.io/?EIO=3&transport=websocket&sid=VsJvZikGdc8spBaPAAMO"
 
headers = {
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
    'Cookie': 'UM_distinctid=16614315bf179b-0354a40c6714ff-34677908-232800-16614315bf2acb; XSRF-TOKEN=eyJpdiI6IkNZRU9uSmM1ZnY2M0VqNUttK1pxRGc9PSIsInZhbHVlIjoiRlJpNlRuekIxTDJZeVd3bHpvXC9OUEZGamw4VndZNEdXTEVsRjRMaFFyOEIxUHRtNDdTc1JaQ042eG4xdjlFeWJjWGlkcWFaeWl6NTRVUUlQMThaZmJ3PT0iLCJtYWMiOiJkYWU1MzQ2NjEyM2U3OTk0MzY5NWNjZTdhZmNlZjE0YTViMjc2YzBiYWM4YjhiMjNhZmRjMzU3YzliNDg3ZGIzIn0%3D; laravel_session=eyJpdiI6IjBRS3h0Y29XcGRBRlFIc0xIeWFiZGc9PSIsInZhbHVlIjoibVRLblpNTDJJa1JIN1ZJc0s5c2xrSkYzckNadDB6aGp0REd5SVJQTlkxNVAzajhvdXY5ZElSQ3VTcGVicjNiSXZ3NE9pZDZOdHJUM1d6WG1KQjZXNkE9PSIsIm1hYyI6Ijg3MWVkZDVlMDFjZDM2NDRjZmI2ZDhkNDJmZGI5MjNhMzk3MTViNmI1YTNmMDRmYWJjNzQ4ZGU2YWZhNzNhNzUifQ%3D%3D; io=VsJvZikGdc8spBaPAAMO',
    'Host': 'sshibikfdn.jin10.com:9084',
    'Connection': 'Upgrade',
    'Origin': 'https://datacenter.jin10.com',
    'Pragma': 'no-cache',
    'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits',
    'Sec-WebSocket-Key': 'g4UA3smEJ0eGufMkyz7AOw==',
    'Sec-WebSocket-Version': '13',
    'Upgrade': 'websocket',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
}
 
 
def get_web_socket():
    start_message = "2probe"
    ws = create_connection(
        api,
        header=headers,
        cookie=headers['Cookie'],
        #origin=headers['Origin'],
        #host=headers['Host']
    )
    frame = ABNF.create_frame("2probe", ABNF.OPCODE_TEXT)
    ws.send_frame(frame)
 
    data = ws.recv_frame()
    print(data)
 
 
if __name__ == '__main__':
    get_web_socket()
 
 

在运行程序之后毫无效果,另外端口的api会根据真实的请求变化 ,而且进一步的请求的cookie和key都会变化 ,看来直连的方式是行不通了,那没办法,只能走渲染的路了,selenium ? 可以是可以,不过我们要尝试一下新的路线和方法,那就直接上chrome-headless

实践

Headless Chrome指在headless模式下运行谷歌浏览器(以程序模式运行,没有界面),自从这玩意儿出来之后, phantomjs的作者就宣布甩锅不维护了(人家也确实辛苦,没啥收益),可以说是一个非常好的 工具 了,咱们说干就干

安装

直接使用 docker 来安装chrome headless

docker run -d -p 9222:9222 --cap-add=SYS_ADMIN justinribeiro/chrome-headless
 

环境

  • python 3.6
  • ubuntu16.04
pip install websocket-client
pip install requests
 

编码

这样我们已经启用了一个chrome headless的服务,那如何使用呢,我们使用websocket 和chrome header less进行交互,不多说了,直接上代码吧

import json
import time
 
import requests
import websocket
 
request_id = 0
target_url = 'https://datacenter.jin10.com/price'
 
 
def get_websocket_connection():
    r = requests.get('http://10.10.2.42:9222/json') #这是开启docker chrome headless的机器地址
    if r.status_code != 200:
        raise ValueError("can not get the api ,please check if docker is ready")
 
    conn_api = r.json()[0].get('webSocketDebuggerUrl')
 
    return websocket.create_connection(conn_api)
 
 
def run_command(conn, method, **kwargs):
    global request_id
    request_id += 1
    command = {'method': method,
               'id': request_id,
               'params': kwargs}
    conn.send(json.dumps(command))
    #while True:
    msg = json.loads(conn.recv())
    if msg.get('id') == request_id:
        return msg
 
 
def get_element():
    conn = get_websocket_connection()
    msg = run_command(conn, 'Page.navigate', url=target_url)
    time.sleep(5)
    js = "var p = document.querySelector('.jin-pricewall_list-item_b').innerText ; p ;"
 
    for _ in range(20):
        time.sleep(1)
        msg = run_command(conn, 'Runtime.evaluate', expression=js)
        print(msg.get('result')['result']['value'])
 
 
if __name__ == '__main__':
    get_element()
 
 

整体逻辑非常简单,打开指定页面,等待页面数据刷新,然后直接偷懒拿数据渲染之后的页面值,运行效果如下:

chrome headless 爬虫抓取websoket 数据

其中的0 是因为页面还在渲染之中,所以数据还没有正式的出现在前台界面上

总结

本次主要使用了chrome-headless的相关渲染环境来解决了我们抓取数据的问题,并且使用了websocket api 来进一步操作,其实google 官方有sdk进行操作,https://github.com/GoogleChrome/puppeteer ,渲染的终究不是高效的做法,但是对于这种单页面目的性很强的数据,可以尝试渲染大法


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First HTML and CSS

Head First HTML and CSS

Elisabeth Robson、Eric Freeman / O'Reilly Media / 2012-9-8 / USD 39.99

Tired of reading HTML books that only make sense after you're an expert? Then it's about time you picked up Head First HTML and really learned HTML. You want to learn HTML so you can finally create th......一起来看看 《Head First HTML and CSS》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具