2025, Oct 17 04:33
Google Sheets iframe में सभी नेटवर्क अनुरोध: Selenium performance लॉग बनाम Playwright
ChromeDriver के Selenium performance लॉग OOPIF iframe ट्रैफिक मिस करते हैं। वजह जानें और Playwright से सभी नेटवर्क डोमेनों को भरोसेमंद ढंग से कैप्चर करें.
जब आप किसी Google Sheets दस्तावेज़ को iframe के जरिए एम्बेड करते हैं और पेज द्वारा किए गए हर नेटवर्क अनुरोध का हिसाब रखने की कोशिश करते हैं, तो अक्सर Selenium के performance लॉग पर भरोसा करने का मन करता है। लेकिन चौंकाने वाली बात तब सामने आती है जब आपकी एकत्र की गई डोमेन‑सूची में सिर्फ टॉप‑लेवल होस्ट ही मिलता है, जबकि Chrome DevTools स्पष्ट रूप से अन्य ओरिजिन्स पर कई अनुरोध दिखाता है। नीचे संक्षेप में बताया गया है कि ऐसा क्यों होता है और इस स्थिति में डोमेनों का पूरा सेट कैसे इकट्ठा करें।
पर्यावरण
ChromeDriver 138.0.7204.168, Chrome 138.0.7204.184, Selenium 4.34.2, Windows 11.
समस्या को दोहराना
एक पेज iframe के जरिए प्रकाशित स्प्रेडशीट एम्बेड करता है:
<html>
  <head>
  </head>
  <body>
    <iframe src="https://docs.google.com/spreadsheets/d/e/2PACX-1vQaJwXqci0KQzDjzs8kvy--p80OZY1n30t4NWRh2qkU3pJqAdB4ZJEc79ohh4OkuifHWOHBRi0Z0yKS/pubhtml?gid=0&single=true&widget=true&headers=false"></iframe>
  </body>
</html>एक Selenium स्क्रिप्ट 'performance' लॉग का उपयोग करके पेज जिन‑जिन डोमेनों से संपर्क करता है, उन्हें कैप्चर करने की कोशिश करती है:
from urllib.parse import urlparse
import json
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
import time
opt = Options()
opt.set_capability('goog:loggingPrefs', {'performance': 'ALL'})
svc = Service(executable_path='C:\\Users\\qi\\PycharmProjects\\PythonLearn\\DomainCollector\\chromedriver.exe')
browser = webdriver.Chrome(service=svc, options=opt)
local_url = "file:///C:/Users/qi/Desktop/a.html"
browser.get(local_url)
time.sleep(5)
hosts = set()
perf_entries = browser.get_log('performance')
for evt in perf_entries:
    raw = evt['message']
    try:
        payload = json.loads(raw)
        evt_type = payload['message']['method']
        if evt_type == 'Network.requestWillBeSent':
            req_url = payload['message']['params']['request']['url']
            host = urlparse(req_url).netloc
            if host:
                hosts.add(host)
    except Exception:
        continue
print(f"domains:{hosts}")आउटपुट में केवल टॉप‑लेवल डोमेन सूचीबद्ध होता है:
domains:{'docs.google.com'}इसी दौरान ब्राउज़र के DevTools अन्य Google ओरिजिन्स और स्थिर एसेट होस्ट्स पर अतिरिक्त ट्रैफिक दिखाते हैं।
असल में हो क्या रहा है
ChromeDriver का 'performance' लॉग क्रॉस‑ओरिजिन iframes से आने वाले नेटवर्क ट्रैफ़िक को भरोसेमंद तरीके से शामिल नहीं करता। आधुनिक Chrome में इन्हें out‑of‑process iframes (OOPIF) कहा जाता है। goog:loggingPrefs के साथ performance=ALL सेट करने से लॉग का स्तर बदलता है, कैप्चर किए जाने वाले targets का दायरा नहीं। perfLoggingPrefs.enableNetwork सक्षम होने पर भी performance लॉग अधिकतर टॉप‑लेवल target से ही जुड़ा रहता है और क्रॉस‑ओरिजिन फ्रेम्स द्वारा किए गए नेटवर्क अनुरोधों को मिस कर देता है। इसी वजह से ऊपर दी गई स्क्रिप्ट docs.google.com तो देखती है, पर iframe द्वारा लोड किए गए अतिरिक्त डोमेनों को नहीं।
कारगर विकल्प जो सभी अनुरोध कैप्चर करता है
इस स्थिति में सभी आउटगोइंग अनुरोध कैप्चर करने का व्यावहारिक तरीका है ऐसा दृष्टिकोण अपनाना जो पूरे पेज—क्रॉस‑ओरिजिन iframes सहित—में नेटवर्क इवेंट्स को ट्रैक करे। इसी काम के लिए Playwright का उपयोग करते हुए, नीचे दिया गया स्क्रिप्ट पेज लोड के दौरान दिखे सभी डोमेनों को एकत्र करता है:
import asyncio
from urllib.parse import urlparse
from playwright.async_api import async_playwright
hosts2 = set()
def on_request(req):
    h = urlparse(req.url).netloc
    if h:
        hosts2.add(h)
async def run():
    async with async_playwright() as pw:
        engine = await pw.chromium.launch(executable_path='..\\DomainCollector\\chrome-win64\\chrome.exe', headless=False)
        tab = await engine.new_page()
        tab.on("request", on_request)
        await tab.goto("file:///C:/Users/qi/Desktop/a.html")
        await tab.wait_for_load_state("networkidle")
asyncio.run(run())
print(f"domains:{hosts2}")परिणाम में ssl.gstatic.com, fonts.gstatic.com, fonts.googleapis.com और docs.google.com जैसे सभी देखे गए होस्ट शामिल होते हैं।
यह क्यों मायने रखता है
यदि आप ऐसा मॉनिटरिंग, क्रॉलिंग या सुरक्षा टूलिंग बनाते हैं जो बाहरी संसाधनों की गणना पर निर्भर है, तो क्रॉस‑ओरिजिन iframe ट्रैफ़िक का छूट जाना अंधे धब्बे पैदा करता है। एम्बेडेड कंटेंट सर्वव्यापी है और बड़े प्लेटफ़ॉर्म अकसर अपने एसेट्स कई डोमेनों में बाँटते हैं। केवल टॉप‑लेवल नेटवर्क इवेंट्स पर निर्भर रहना मैट्रिक्स को बिगाड़ सकता है, थर्ड‑पार्टी कॉल्स छिपा सकता है और ओरिजिन‑आधारित पॉलिसी प्रवर्तन को प्रभावित कर सकता है।
मुख्य बातें
जब आपके लक्ष्य पेज में क्रॉस‑ओरिजिन iframes हों, तो केवल ChromeDriver का performance लॉग नेटवर्क का पूरा दृश्य नहीं देता। यह तंत्र मुख्य target की ओर उन्मुख है और OOPIF ट्रैफ़िक को लगातार कवर नहीं करता। जहाँ पूर्ण कैप्चर जरूरी हो, वहाँ ऐसा टूलिंग अपनाएँ जो पेज के सभी फ्रेम्स में होने वाले अनुरोधों का निरीक्षण करे। ऊपर दिए उदाहरण में Playwright यह कवरेज डिफ़ॉल्ट रूप से देता है और अपेक्षित डोमेनों का सेट लौटाता है। एम्बेडेड कंटेंट के इर्द‑गिर्द डेटा संग्रह पाइपलाइनों को डिज़ाइन करते समय इसे ध्यान में रखें, ताकि अंडर‑रिपोर्टिंग से बचा जा सके और दृश्यता सटीक बनी रहे।