--- id: "09721f1c-2a81-4d26-a2e7-ba9f176f2b74" name: "Iframe Content Extraction" micro_summary: "Extracts McGraw-Hill question content through the dynamically named iframe's contentWindow.document; iframe_target() leaves JS in the parent context." status: "not_examined" see_also: [] scope: "How to extract content from nested iframes in McGraw-Hill Connect and SIMbook pages. The iframe_target() helper doesn't change CDP execution context, so you must reach into iframes from the parent page via contentWindow.document." warnings: "iframe name attribute is dynamically generated (e.g., Q_13252744676035422_ansb) — never hardcode it. Find via js('document.querySelector(\\\"iframe\\\").name') or search by src pattern." --- ## The Problem McGraw-Hill Connect and SIMnet load actual question content inside nested iframes. The parent page shows only the shell (nav, buttons, progress bar). `extract_text()` and `js()` run in the parent CDP context — they never see iframe content. ## The Working Pattern Use parent-page JS to reach into the iframe via `contentWindow.document`: **Step 1: Find the iframe name/selector** ```python js('document.querySelector(\"iframe\").name') # → Q_13252744676035422_ansb (dynamic, changes per assignment) ``` **Step 2: Extract content in chunks from parent context** ```python js('document.querySelector(\"iframe[name=\\\"\\\"]\")?.contentWindow?.document?.body?.innerHTML.substring(0, 5000)') js('document.querySelector(\"iframe[name=\\\"\\\"]\")?.contentWindow?.document?.body?.innerHTML.substring(5000, 12000)') ``` **Reusable template:** ```python js('document.querySelector(\"iframe[name=\\\"\\\"]\")?.contentWindow?.document?.body?.innerHTML.substring(, )') ``` Chunk with increasing ranges until you have all the content. Parse the HTML for tables, dropdowns (`role=combobox`), and question text. ## What Does NOT Work - `iframe_target()` — switches visual focus but NOT CDP execution context. `js()` and `extract_text()` still run on the parent page. - `document.body.innerHTML` on iframe from Python — same-origin policy may block direct access, but `contentWindow.document` works because CDP executes in the same browsing context. ## Finding Iframes Dynamically The iframe `name` attribute is dynamically generated (e.g., `Q_13252744676035422_ansb`). To find it: ```python js('document.querySelector(\"iframe\").name') # first iframe # or search by src pattern: js('document.querySelector(\"iframe[src*=\\\"accountingtool\\\"]\").name') ```