12

I need to receive data from a website over a websocket connection. Access to the websocket is only given after logging into the website. Using a session in python requests I am able to post my login information to the login page and authenticate my details. Websocket-client would be used for the creating the websocket connection to the website however the websocket connection created would not be through the login session.

How can I create a websocket connection after logging in through requests?

I found a similiar question here but it has not been answered Python - Websockets Unable to validate my session

This is my code so far (simplified a bit).

import requests
from bs4 import BeautifulSoup
import base64
import random
import websocket

headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'}

payload = {
    'username': 'username',
    'password': 'password'}

session = requests.Session()

r = session.get("https://www.example.com/login", headers=headers)

soup = BeautifulSoup(r.content, 'html.parser')
payload['token'] = soup.find('input', attrs={'name': 'token'})['value']

r = session.post("https://www.example.com/login", data=payload, headers=headers)
r = session.get("https://www.example.com/", headers=headers)

headers['Sec-WebSocket-Key'] = str(base64.b64encode(bytes([random.randint(0, 255) for _ in range(16)])), 'ascii')
headers['Sec-WebSocket-Version'] = '13'
headers['Upgrade'] = 'websocket'

ws = websocket.WebSocketApp('wss://www.example.com/streaming/',
                            header=headers,
                            #session=session????)
ws.run_forever()
0

1 Answer 1

17

After much searching I eventually found the source of the problem. I was using Chrome Dev Tools to view the network packets when accessing the website through chrome browser, however Chrome Dev Tools does not show cookies for a websocket request. Firefox Developer Tools does show the cookies for a websocket request and I only discovered what cookies were being sent when I used Firefox. The solution is to extract the cookies for the Requests Session, and pass these cookies to the WebSocketApp. That way the websocket server can verify you are logged in.

cookies = session.cookies.get_dict()
ws = websocket.WebSocketApp('wss://www.example.com/streaming/',
                        header=headers,
                        cookie="; ".join(["%s=%s" %(i, j) for i, j in cookies.items()]))
Sign up to request clarification or add additional context in comments.

1 Comment

This method gets the cookies and headers from the requests.Session(), but does not use it. When using an authenticated session, such as one created by requests_html, it will try to bypass it and fail.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.