Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to access elements within Iframe , seems especial cross domain iframe #469

Open
peaceyourself opened this issue Mar 24, 2024 · 1 comment

Comments

@peaceyourself
Copy link

env:

Operating System: Windows or macOS
Browser: Chrome version 117 or higher (tested with versions 117, 122)
Pyppeteer: v1.0.2

Issue Description:

Unable to retrieve iframes with page.frames when the URL belongs to a different domain, such as:

Cloudflare frame within a page hosted on Cloudflare, for example: https://artio.faucet.berachain.com/
Iframe present in other pages like https://espn.com/login
Disabling Disable site isolation in chrome://flags/ enables the retrieval of iframes. However, this causes Cloudflare validation failure.

Disabling chrome://flags/#site-isolation-trial-opt-out

You can test this with a page like: https://artio.faucet.berachain.com/

Solutions found online are ineffective:

const browser = await puppeteer.launch({
  args: [
      '--disable-web-security',
      '--disable-features=IsolateOrigins,site-per-process',
    ]
 })

This is the demo, start a local chrome on port xxx, and then connect with pyppeteer.

import asyncio
import requests
from pyppeteer import connect
from browser.pyppeteer_metamask_automation import ExtensionMetamaskManager
import time

class PyppeteerTest:
    def __init__(self):
        self.browser = None

    async def get_browser(self, port):
        option = {
            'browserURL': f'http://127.0.0.1:{port}',
            'defaultViewport': None
        }
        return await connect(option)

    async def close_browser(self):
        if self.browser:
            await self.browser.close()

    async def main(self):
        self.browser = await self.get_browser(9222)
        if not self.browser:
            print("Browser not initialized.")
            return

        page = await self.browser.newPage()

        # await page.goto('https://espn.com/login')
        await page.goto('https://artio.faucet.berachain.com')
        await page.waitFor(5 * 1000)

        print('Entering input....')
        input_test = await page.xpath("//input[1]")
        print("input_test:", input_test)
        if input_test:
            await input_test[0].type('0x553858D4986DF308F73C71e51B8739a4F7255b97')
            await page.waitFor(1 * 1000)

        await page.waitFor(3 * 1000)

        await page.waitForSelector('iframe[sandbox="allow-same-origin allow-scripts allow-popups"]')
        frames = page.frames
        print("frames:", frames)
        for frame in frames:
            name = frame.name
            print("frame_name:", name)

        if frame:
            await page.waitFor(5 * 1000) #等待验证码加载完毕
            print('切换到 iframe 中...:', frame)
            button = await frame.xpath("//input[@type='checkbox']")
            print("button:", button)
            button = await frame.querySelector('input[type="checkbox"]')
            print("button:", button)
            if button:
                print('点击按钮...:', button)
                await button[0].click()
                print('按钮已点击。')
            else:
                print("未检测到验证码")
        else:
            print("未找到符合条件的iframe")


async def main():
    pyppeteer_test = PyppeteerTest()
    await pyppeteer_test.main()

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

@devblack
Copy link

devblack commented Apr 5, 2024

Try:

const frameHandle = await page.$('iframe[sandbox="allow-same-origin allow-scripts allow-popups"]');
if (frameHandle) {
   const frame = await frameHandle.contentFrame();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants