{ "info": { "author": "Mark E. Haase ", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Libraries" ], "description": "# Trio CDP\n\n[![PyPI](https://img.shields.io/pypi/v/trio-chrome-devtools-protocol.svg)](https://pypi.org/project/trio-chrome-devtools-protocol/)\n![Python Versions](https://img.shields.io/pypi/pyversions/trio-chrome-devtools-protocol)\n![MIT License](https://img.shields.io/github/license/HyperionGray/trio-chrome-devtools-protocol.svg)\n[![Build Status](https://img.shields.io/travis/com/HyperionGray/trio-chrome-devtools-protocol.svg?branch=master)](https://travis-ci.com/HyperionGray/trio-chrome-devtools-protocol)\n\nThis Python library performs remote control of any web browser that implements\nthe Chrome DevTools Protocol. It is built using the type wrappers in\n[python-chrome-devtools-protocol](https://py-cdp.readthedocs.io) and implements\nI/O using [Trio](https://trio.readthedocs.io/). This library handles the\nWebSocket negotiation and session management, allowing you to transparently\nmultiplex commands, responses, and events over a single connection.\n\nThe example demonstrates the salient features of the library.\n\n```python\nasync with open_cdp_connection(cdp_url) as conn:\n # Find the first available target (usually a browser tab).\n targets = await conn.execute(target.get_targets())\n target_id = targets[0].id\n\n # Create a new session with the chosen target.\n session = await conn.open_session(target_id)\n\n # Navigate to a website.\n await session.execute(page.enable())\n async with session.wait_for(page.LoadEventFired):\n await session.execute(page.navigate(target_url))\n\n # Extract the page title.\n root_node = await session.execute(dom.get_document())\n title_node_id = await session.execute(dom.query_selector(root_node.node_id,\n 'title'))\n html = await session.execute(dom.get_outer_html(title_node_id))\n print(html)\n```\n\nWe'll go through this example bit by bit. First, it starts with a context\nmanager:\n\n```python\nasync with open_cdp_connection(cdp_url) as conn:\n```\n\nThis context manager opens a connection to the browser when the block is entered\nand closes the connection automatically when the block exits. Now we have a\nconnection to the browser, but the browser has multiple targets that can be\noperated independently. For example, each browser tab is a separate target. In\norder to interact with one of them, we have to create a session for it.\n\n```python\ntargets = await conn.execute(target.get_targets())\ntarget_id = targets[0].id\n```\n\nThe first line here executes the `get_targets()` command in the browser. Note\nthe form of the command: `await conn.execute(...)` will send a command to the\nbrowser, parse its response, and return a value (if any). The command is one of\nthe methods in the PyCDP package. Trio CDP multiplexes commands and responses on\na single connection, so we can send commands concurrently if we want, and the\nresponses will be routed back to the correct task.\n\nIn this case, the command is `target.get_targets()`, which returns a list of\n`TargetInfo` objects. We grab the first object and extract its `target_id`.\n\n```python\nsession = await conn.open_session(target_id)\n```\n\nIn order to connect to a target, we open a session based on the target ID.\n\n```python\nawait session.execute(page.enable())\nasync with session.wait_for(page.LoadEventFired):\n await session.execute(page.navigate(target_url))\n```\n\nHere we use the session (remember, it corresponds to a tab in the browser) to\nnavigate to the target URL. Just like the connection object, the session object\nhas an `execute(...)` method that sends a command to the target, parses the\nresponse, and returns a value (if any).\n\nThis snippet also introduces another concept: events. When we ask the browser to\nnavigate to a URL, it acknowledges our request with a response, then starts the\nnavigation process. How do we know when the page is actually loaded, though?\nEasy: the browser can send us an event!\n\nWe first have to enable page-level events by calling `page.enable()`. Then we\nuse `session.wait_for(...)` to wait for an event of the desired type. In this\nexample, the script will suspend until it receives a `page.LoadEventFired`\nevent.\n\nNote that we wait for the event inside an `async with` block, and we do this\n_before_ executing the command that will trigger this event. This order of\noperations may be surprising, but it avoids race conditions. If we executed a\ncommand and then tried to listen for an event, the browser might fire the event\nvery quickly before we have had a chance to set up our event listener, and then\nwe would miss it! The `async with` block sets up the listener before we run the\ncommand, so that no matter how fast the event fires, we are guaranteed to catch\nit.\n\n```python\nroot_node = await session.execute(dom.get_document())\ntitle_node_id = await session.execute(\n dom.query_selector(root_node.node_id, 'title'))\nhtml = await session.execute(dom.get_outer_html(title_node_id))\nprint(html)\n```\n\nThe last part of the script navigates the DOM to find the `` element.\nFirst we get the document's root node, then we query for a CSS selector, then\nwe get the outer HTML of the node. This snippet shows some new APIs, but the\nmechanics of sending commands and getting responses are the same as the previous\nsnippets.\n\nA more complete version of this example can be found in `examples/get_title.py`.\nThere is also a screenshot example in `examples/screenshot.py`. The unit tests\nin `test/` also provide more examples.\n\n<a href=\"https://www.hyperiongray.com/?pk_campaign=github&pk_kwd=trio-cdp\"><img alt=\"define hyperion gray\" width=\"500px\" src=\"https://hyperiongray.s3.amazonaws.com/define-hg.svg\"></a>", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/HyperionGray/trio-chrome-devtools-protocol", "keywords": "trio chrome devtools protocol cdp", "license": "", "maintainer": "", "maintainer_email": "", "name": "trio-chrome-devtools-protocol", "package_url": "https://pypi.org/project/trio-chrome-devtools-protocol/", "platform": "", "project_url": "https://pypi.org/project/trio-chrome-devtools-protocol/", "project_urls": { "Homepage": "https://github.com/HyperionGray/trio-chrome-devtools-protocol" }, "release_url": "https://pypi.org/project/trio-chrome-devtools-protocol/0.2.0/", "requires_dist": null, "requires_python": ">=3.7", "summary": "Trio driver for Chrome DevTools Protocol (CDP)", "version": "0.2.0" }, "last_serial": 5810528, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "4a98ff1d870161b8244d8d7dfcc47a41", "sha256": "a4c3d632dfd4065e39837be28e6842dd0eaa974ef8343a7bfb18105c6704d03f" }, "downloads": -1, "filename": "trio-chrome-devtools-protocol-0.1.0.tar.gz", "has_sig": false, "md5_digest": "4a98ff1d870161b8244d8d7dfcc47a41", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 7926, "upload_time": "2019-08-30T16:04:03", "url": "https://files.pythonhosted.org/packages/e3/d7/ac51d71f428d6caf1399ae65a0efa0bac8e39e492c5816ec6ebf2627d0c3/trio-chrome-devtools-protocol-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "85a6d0ba69650a43a1f2675cac924f42", "sha256": "96ab428b161461dbc2886fba80eb70fa2b4bfb79b43295246fbe163712aa4234" }, "downloads": -1, "filename": "trio-chrome-devtools-protocol-0.2.0.tar.gz", "has_sig": false, "md5_digest": "85a6d0ba69650a43a1f2675cac924f42", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 8496, "upload_time": "2019-09-10T18:22:33", "url": "https://files.pythonhosted.org/packages/16/31/cc38ccd9d0df1fa39dff3212e2519746795385eca2303650a4c9e692fa14/trio-chrome-devtools-protocol-0.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "85a6d0ba69650a43a1f2675cac924f42", "sha256": "96ab428b161461dbc2886fba80eb70fa2b4bfb79b43295246fbe163712aa4234" }, "downloads": -1, "filename": "trio-chrome-devtools-protocol-0.2.0.tar.gz", "has_sig": false, "md5_digest": "85a6d0ba69650a43a1f2675cac924f42", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.7", "size": 8496, "upload_time": "2019-09-10T18:22:33", "url": "https://files.pythonhosted.org/packages/16/31/cc38ccd9d0df1fa39dff3212e2519746795385eca2303650a4c9e692fa14/trio-chrome-devtools-protocol-0.2.0.tar.gz" } ] }