ClericPy / ichrome

Chrome controller for Humans, based on Chrome Devtools Protocol(CDP) and python3.7+.
https://pypi.org/project/ichrome/
MIT License
228 stars 29 forks source link

chrome cdp do not support non-localhost without --headless, need the port forwarding #84

Closed ClericPy closed 2 years ago

ClericPy commented 2 years ago

https://stackoverflow.com/questions/6827310/chrome-remote-debugging-doesnt-work-with-ip

The default chrome debug mode does not support non-headless mode when opening remote access:

  1. localhost + --headless runs ok
  2. localhost without --headless runs ok
  3. lan-ip + --headless runs ok
  4. lan-ip without headless fails

So far there is not any ways to fix it, so you should try some ways of forward proxy for this:


import asyncio

class ForwardedConnection(asyncio.Protocol):

    def __init__(self, peer):
        self.peer = peer
        self.transport = None
        self.buff = []

    def connection_made(self, transport):
        self.transport = transport
        if self.buff:
            self.transport.writelines(self.buff)
            self.buff.clear()

    def data_received(self, data):
        self.peer.write(data)

    def connection_lost(self, e):
        if self.peer:
            self.peer.close()

class PortForwarder(asyncio.Protocol):

    def __init__(self, dst_host, dst_port):
        self.dst_host = dst_host
        self.dst_port = dst_port

    async def connection_daemon(self):
        try:
            await asyncio.get_running_loop().create_connection(
                lambda: self.fc, self.dst_host, self.dst_port)
        except Exception:
            return

    def connection_made(self, transport):
        self.transport = transport
        self.fc = ForwardedConnection(self.transport)
        asyncio.ensure_future(self.connection_daemon())

    def data_received(self, data):
        if self.fc.transport is None:
            self.fc.buff.append(data)
        else:
            self.fc.transport.write(data)

    def connection_lost(self, e):
        if self.fc.transport:
            self.fc.transport.close()

    @classmethod
    async def start_server(cls, dst_host, dst_port, src_host, src_port):
        server = await asyncio.get_running_loop().create_server(
            lambda: cls(dst_host, dst_port), src_host, src_port)
        return server

async def _main():
    server = await PortForwarder.start_server('127.0.0.1', 9222, '172.1.1.11',
                                              9221)
    await server.wait_closed()

def main():
    asyncio.run(_main())

if __name__ == '__main__':
    main()
ClericPy commented 2 years ago

ichrome version 3.0.0+

from ichrome import AsyncChromeDaemon
from ichrome.utils import PortForwarder

lan_ip = '192.168.0.100'
async with PortForwarder(('127.0.0.1', 9222), (lan_ip, port)):
    async with AsyncChromeDaemon() as cd: