Как использовать сеть / xhr, чтобы найти содержимое таблиц на этой странице? - PullRequest
0 голосов
/ 29 марта 2020

Я пытаюсь использовать следующий код для доступа к содержимому следующей таблицы на этой странице: https://cdn.ime.co.ir

enter image description here

По этому коду:

import requests
with requests.Session() as s:
    data = {'ContractCode' : 'SAFOR99' }
    r = s.post('https://cdn.ime.co.ir/home/load/' , json = data ).json()
    print(r)

Но в результате я вижу следующее:

JSONDecodeError: Ожидаемое значение

Пожалуйста, помогите мне знаете, как я могу прочитать содержимое этой таблицы?

1 Ответ

1 голос
/ 30 марта 2020

Данные не содержатся в содержимом html, но они извлекаются через API и, более конкретно, протокол - websocket. Вы можете проверить фреймы с помощью Chrome devtools и отфильтровать по wss, чтобы найти следующий URL: wss://cdn.ime.co.ir/realTimeServer/connect

Существует несколько необходимых параметров запроса, включая connectionToken, который выбирается через API отдыха на https://cdn.ime.co.ir/realTimeServer/negotiate ,

После того, как вы откроете веб-сокет, вы не получите много данных, пока не выполните другой запрос отдыха на https://cdn.ime.co.ir/realTimeServer/start с тем же значением ConnectionToken. После этого сервер отправляет вам JSON данные

Следующий код выполняет все описанные выше задачи, и вы получаете данные в result нефильтрованном списке:

import requests
import json
import asyncio
import websockets
import urllib
import random
from threading import Thread

connectionData = [{"name":"marketshub"}]

r = requests.get("https://cdn.ime.co.ir/realTimeServer/negotiate", params = {
    "clientProtocol": "2.1",
    "connectionData": json.dumps(connectionData),
})
response = r.json()

print(f'got connection token : {response["ConnectionToken"]}')

wsParams = {
    "transport": "webSockets",
    "clientProtocol": "2.1",
    "connectionToken": response["ConnectionToken"],
    "connectionData": json.dumps(connectionData),
    "tid": random.randint(0,9)
}

websocketUri = f"wss://cdn.ime.co.ir/realTimeServer/connect?{urllib.parse.urlencode(wsParams)}"

def startReceiving(arg):
    r = requests.get("https://cdn.ime.co.ir/realTimeServer/start", params = wsParams)
    print(f'started receiving data : {r.json()}')

result = []

async def websocketConnect():
    async with websockets.connect(websocketUri) as websocket:
        print(f'started websocket')
        thread = Thread(target = startReceiving, args = (0, ))
        thread.start()
        for i in range(0,10):
            print("receiving")
            data = await websocket.recv()
            jsonData = json.loads(data)
            if ("M" in jsonData and len(jsonData["M"]) > 0 and "A" in jsonData["M"][0] and len(jsonData["M"][0]["A"]) > 0):
                items = jsonData["M"][0]["A"][0]
                if type(items) == list and len(items) > 0: 
                    result = items
                    break
        thread.join()
        print(json.dumps(result, indent=4, sort_keys=True))

asyncio.get_event_loop().run_until_complete(websocketConnect())

Затем Вы можете получить предмет SAFOR99, используя:

print([i for i in result if i["ContractCode"] == "SAFOR99"])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...