🎯 कस्टमाइज़ करने योग्य, डिटेक्शन-प्रतिरोधी क्लाउड ब्राउज़र जो स्व-विकसित Chromium द्वारा संचालित है, वेब क्रॉलर और एआई एजेंट्स के लिए डिज़ाइन किया गया। 👉अभी आज़माएं
वापस ब्लॉग पर

म्यूटेशन ऑब्जर्वर और प्लेह्राइट के साथ गतिशील DOM परिवर्तनों को कैप्चर करें

Isabella Garcia
Isabella Garcia

Web Data Collection Specialist

30-Jul-2026

TL;DR:

  • गतिशील पृष्ठ प्रारंभिक HTML लोड होने के बाद DOM को बदल सकते हैं। एक स्क्रैपर को उपयोग करने योग्य स्थिति के लिए इंतजार करना चाहिए, बजाय पहले उत्तर को अंतिम दस्तावेज़ मानने के।
  • MutationObserver DOM में बदलावों को दर्ज करता है। जब आपको जोड़े गए नोड, हटाए गए नोड, टेक्स्ट अपडेट या विशेषता संक्रमण की आवश्यकता हो, तो ट्रिगर क्रियावली से पहले अवलोकनकर्ता स्थापित करें।
  • Playwright लोकेटर आवश्यक स्थिति के उपयोग के लिए पुष्टि की प्रतीक्षा करता है। परिवर्तन की उत्पत्ति के लिए अवलोकनकर्ता का उपयोग करें और अंतिम स्थिति की तत्परता के लिए लोकेटर।
  • एक सीमित अवलोकनकर्ता केवल प्रासंगिक उप-गाछ और उत्परिवर्तन प्रकारों की निगरानी करनी चाहिए। छोटे रिकॉर्ड को सीरियलाइज़ करें, शोर वाले गुणों को फ़िल्टर करें, और अपेक्षित स्थिति प्रकट होने के बाद संपर्क कटें।
  • नेटवर्क अवरोधन आमतौर पर तब बेहतर होता है जब संरचित प्रतिक्रिया डेटा वास्तविक लक्ष्य होता है। MutationObserver सबसे उपयोगी है जब स्वयं DOM संक्रमण महत्वपूर्ण होता है।
  • समान अवलोकन कार्यप्रविधि स्थानीय रूप से और Scrapeless के माध्यम से चलती है। Scrapeless वेब स्क्रैपिंग ब्राउज़र पर जाने से ब्राउज़र निर्माण बदलता है, न कि पृष्ठ-पक्ष के अवलोकनकर्ता।
  • शुरू करने के लिए स्वतंत्र। नए Scrapeless खातों में मुफ्त वेब स्क्रैपिंग ब्राउज़र रनटाइम शामिल है—app.scrapeless.com पर साइन अप करें।

परिचय: प्रारंभिक HTML केवल प्रारंभिक स्थिति है

एक गतिशील पृष्ठ अपने प्रारंभिक HTML लोड होने के बाद डेटा डाल सकता है, प्रकट कर सकता है, बदल सकता है या हटा सकता है। यह मार्गदर्शिका एक सीमित MutationObserver स्थापित करती है, एक सार्वजनिक Selenium फ़िक्स्चर को ट्रिगर करने से पहले DOM में सटीक परिवर्तन कैप्चर करती है, और Playwright के लोकेटर की प्रतीक्षा के साथ ईवेंट-प्रेरित अवलोकन की तुलना करती है, इससे पहले कि उसी कार्यप्रविधि को Scrapeless वेब स्क्रैपिंग ब्राउज़र में स्थानांतरित किया जाए।

MutationObserver स्क्रैपिंग में क्या जोड़ता है

MutationObserver DOM उप-गाछ में परिवर्तनों की रिपोर्ट करता है। यह बच्चे के सम्मिलन/हटाव, गुण और टेक्स्ट परिवर्तनों पर नज़र रख सकता है बिना पृष्ठ को बार-बार स्कैन किए। MDN का MutationObserver संदर्भ प्रतिक्रिया और अवलोकन विकल्पों को परिभाषित करता है।

एक अवलोकनकर्ता स्वयं यह निर्धारित नहीं करता कि डेटा कब तैयार है। यह जो बदला है उसे दर्ज करता है। Playwright लोकेटर किसी विशेष उपयोगी तत्व के लिए प्रतीक्षा करने का स्पष्ट तरीका बना रहता है, जबकि अवलोकनकर्ता रिकॉर्ड बताते हैं कि वह स्थिति कैसे और कब प्रकट हुई।

Scrapeless के साथ Playwright का उपयोग क्यों करें

Playwright पृष्ठ में ट्रिगर क्लिक से पहले एक अवलोकनकर्ता स्थापित कर सकता है, क्रिया कर सकता है, अंतिम UI स्थिति के लिए प्रतीक्षा कर सकता है, और एक संक्षिप्त ईवेंट लॉग लौटाता है। Scrapeless वेब स्क्रैपिंग ब्राउज़र उसी पृष्ठ-पक्ष के स्क्रिप्ट के लिए एक होस्टेड Chromium सत्र प्रदान करता है।

क्लाउड ब्राउज़र का उपयोग करता है connect_over_cdp। केवल ब्राउज़र निर्माण में बदलाव होता है।

आवश्यकताएँ

  • Python 3.10 या उसके बाद।
  • playwright 1.59.0 या एक वर्तमान संगत संस्करण।
  • पूर्ण लाइव उदाहरण के लिए स्थानीय Chrome/Chromium।
  • क्लाउड कनेक्शन के लिए एक वित्त पोषित Scrapeless खाता और SCRAPELESS_API_KEY। सत्यापन खाते ने 14500 कोड लौटाया, इसलिए वह कनेक्शन एक लेबल वाला आवश्यक गैप है।

स्थापित करें

bash Copy
python -m pip install "playwright==1.59.0"

Scrapeless वेब स्क्रैपिंग ब्राउज़र से कनेक्ट करें

नोट: यह ब्लॉक वित्त पोषित स्क्रैपिंग ब्राउज़र बैलेंस की आवश्यकता है। अंतिम सत्यापन खाते ने संवृद्धि बैलेंस नहीं है, कृपया पहले रीचार्ज करें; पूर्ण अवलोकनकर्ता कार्यप्रविधि नीचे स्थानीय Chrome में चली गई।

python Copy
import os
from urllib.parse import urlencode
from playwright.sync_api import sync_playwright

params = urlencode({
    "token": os.environ["SCRAPELESS_API_KEY"],
    "sessionTTL": 120,
    "proxyCountry": "US",
})
cdp_url = f"wss://browser.scrapeless.com/api/v2/browser?{params}"

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(cdp_url)
    page = browser.contexts[0].pages[0]
    # नीचे अवलोकनकर्ता स्थापित करें और उपयोग करें।
    browser.close()

वर्तमान कनेक्शन पैरामीटर के लिए Scrapeless डेवलपर दस्तावेज़ का उपयोग करें।

चरण 1 — पृष्ठ की प्रारंभिक स्थिति की जांच करें

Selenium का सार्वजनिक फ़िक्स्चर दो बटन प्रकट करता है। एक एक सेकंड बाद #box0 जोड़ता है; दूसरा एक सेकंड बाद एक छिपा हुआ #revealed इनपुट प्रकट करता है:

python Copy
TARGET_URL = "https://www.selenium.dev/selenium/web/dynamic.html"

page.goto(TARGET_URL, wait_until="domcontentloaded")
print("box before:", page.locator("#box0").count())
print("input visible before:", page.locator("#revealed").is_visible())
text Copy
box before: 0
input visible before: False

फिक्स्चर का प्रारंभिक HTML छिपे हुए इनपुट को शामिल करता है लेकिन बॉक्स को नहीं। यही अंतर है कि अवलोकनकर्ता को बच्चे की सूची और विशेषता उत्परिवर्तन दोनों की निगरानी करनी चाहिए।

चरण 2 — क्रिया से पहले अवलोकनकर्ता स्थापित करें

साधारण शब्दकोशों को स्टोर करें न कि DOM नोड्स। MutationRecord परिवर्तन के प्रकार, लक्ष्य, बदला हुआ गुण, और जोड़े/हटाए गए नोड्स का खुलासा करता है।

python Copy
page.evaluate("""
    window.capturedMutations = [];
    window.scrapeObserver = new MutationObserver(records => {
        for (const record of records) {
            for (const node of record.addedNodes) {
                if (node.nodeType === Node.ELEMENT_NODE) {
                    capturedMutations.push({
                        type: 'added',
                        id: node.id,
                        display: getComputedStyle(node).display,
                    });
                }
            }
            if (record.type === 'attributes') {
                capturedMutations.push({
                    type: 'attribute',
                    id: record.target.id,
                    name: record.attributeName,
                    display: getComputedStyle(record.target).display,
                });
            }
        }
    });
    scrapeObserver.observe(document.body, {
        childList: true,
        subtree: true,
        attributes: true,
        attributeFilter: ['style'],
    });
""")

attributeFilter इस सीमाबद्ध कैप्चर से अनसंबंधित वर्ग, ARIA, या ढांचा गुणों को बाहर रखता है।

चरण 3 - परिवर्तनों को ट्रिगर करें और उपयोग योग्य स्थिति की प्रतीक्षा करें

python Copy
page.click("#adder")
page.click("#reveal")
page.wait_for_selector("#box0")
page.locator("#revealed").wait_for(state="visible")

Playwright का स्वचालित प्रतीक्षा मार्गदर्शन यह समझाता है कि Locator सही तत्परता जांच क्यों हैं। पर्यवेक्षक लॉग समग्र अंतिम-स्थिति जोर देने के लिए पूरक साक्ष्य है, न कि प्रतिस्थापन।

चरण 4 - पर्यवेक्षक को डिस्कनेक्ट करें और रिकॉर्ड पढ़ें

python Copy
changes = page.evaluate("""() => {
    scrapeObserver.disconnect();
    return capturedMutations;
}""")

print("changes:", changes)
print("change count:", len(changes))
print("box matches:", page.locator("#box0").count())
print("input visible:", page.locator("#revealed").is_visible())
text Copy
changes: [{'type': 'added', 'id': 'box0', 'display': 'block'}, {'type': 'attribute', 'id': 'revealed', 'name': 'style', 'display': 'inline-block'}]
change count: 2
box matches: 1
input visible: True

डिस्कनेक्ट करने से बाद में अनसंबंधित पृष्ठ परिवर्तनों को घटना सूची का विस्तार करने से रोका जाता है। एक दीर्घकालिक पर्यवेक्षक के लिए हमेशा एक स्पष्ट थामने की स्थिति होनी चाहिए।

क्या आप एक होस्टेड ब्राउज़र सत्र को देखने के लिए तैयार हैं? एक मुफ्त Scrapeless खाता बनाएं और केवल ब्राउज़र निर्माण को बदलें।

संपूर्ण चलने योग्य कैप्चर

python Copy
from playwright.sync_api import sync_playwright

TARGET_URL = "https://www.selenium.dev/selenium/web/dynamic.html"

with sync_playwright() as p:
    browser = p.chromium.launch(
        executable_path="/usr/bin/google-chrome",
        headless=True,
    )
    page = browser.new_page()
    page.goto(TARGET_URL, wait_until="domcontentloaded")

    box_before = page.locator("#box0").count()
    input_before = page.locator("#revealed").is_visible()

    page.evaluate("""
        window.capturedMutations = [];
        window.scrapeObserver = new MutationObserver(records => {
            for (const record of records) {
                for (const node of record.addedNodes) {
                    if (node.nodeType === Node.ELEMENT_NODE) {
                        capturedMutations.push({
                            type: 'added',
                            id: node.id,
                            display: getComputedStyle(node).display,
                        });
                    }
                }
                if (record.type === 'attributes') {
                    capturedMutations.push({
                        type: 'attribute',
                        id: record.target.id,
                        name: record.attributeName,
                        display: getComputedStyle(record.target).display,
                    });
                }
            }
        });
        scrapeObserver.observe(document.body, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['style'],
        });
    """)

    page.click("#adder")
    page.click("#reveal")
    page.wait_for_selector("#box0")
    page.locator("#revealed").wait_for(state="visible")

    changes = page.evaluate("""() => {
        scrapeObserver.disconnect();
        return capturedMutations;
    }""")
    box_after = page.locator("#box0").count()
    input_after = page.locator("#revealed").is_visible()

    assert box_before == 0 and input_before is False
    assert changes == [
        {"type": "added", "id": "box0", "display": "block"},
Here is the translated text in Hindi:

```json
{
  "type": "attribute",
  "id": "revealed",
  "name": "style",
  "display": "inline-block"
},
]
assert box_after == 1 and input_after is True

print("बॉक्स पहले:", box_before)
print("इनपुट दृश्य पहले:", input_before)
print("परिवर्तन:", changes)
print("परिवर्तन की संख्या:", len(changes))
print("बॉक्स बाद में:", box_after)
print("इनपुट दृश्य बाद में:", input_after)
browser.close()

अंतिम क्रिया ने ठीक एक जोड़ा गया नोड और एक शैली-विशेषता परिवर्तन को कैप्चर किया, फिर स्वतंत्र रूप से एक बॉक्स और एक दृश्य इनपुट की पुष्टि की।

आपको क्या मिलता है

पूर्ण कार्यप्रवाह एक कॉम्पैक्ट म्यूटेशन लॉग के साथ स्वतंत्र अंतिम-राज्य जाँचों को लौटाता है:

json Copy
{
  "before": {
    "box_matches": 0,
    "input_visible": false
  },
  "mutations": [
    {
      "type": "added",
      "id": "box0",
      "display": "block"
    },
    {
      "type": "attribute",
      "id": "revealed",
      "name": "style",
      "display": "inline-block"
    }
  ],
  "after": {
    "box_matches": 1,
    "input_visible": true
  }
}

म्यूटेशन रिकॉर्ड बताते हैं कि पृष्ठ कैसे बदला, जबकि लोकेटर जाँचें पुष्टि करती हैं कि अंतिम तत्व उपयोग योग्य हैं। दोनों को रखने से यह सुनिश्चित होता है कि एक देखा गया घटना पूर्ण UI ट्रांज़िशन के रूप में गलत न समझा जाए।

सही डायनामिक-पृष्ठ संकेत का चयन करना

संकेत इसका उपयोग कब करें यह क्या लौटाता है मुख्य सीमा
MutationObserver DOM परिवर्तनों का अनुक्रम या प्रकार मायने रखता है जोड़ा गया, हटाया गया, पाठ, या विशेषता म्यूटेशन सीमित दायरा और एक स्पष्ट रोकने की स्थिति की आवश्यकता होती है
Playwright locator wait केवल अंतिम उपयोगी स्थिति मायने रखती है एक तैयार तत्व या पुष्टि की गई स्थिति यह बताता नहीं है कि पृष्ठ उस स्थिति तक कैसे पहुंचा
नेटवर्क कैप्चर संरचित डेटा अनुरोधों के माध्यम से आता है अनुरोध और प्रतिक्रिया पेलोड बाद की DOM रूपांतरणों का वर्णन नहीं करता
सीमित पोलिंग कोई स्थिर घटना, अनुरोध, या लोकेटर मौजूद नहीं है समय-समय पर स्थिति स्नैपशॉट बार-बार जाँचें शोर और पृष्ठ कार्य जोड़ती हैं

एक लोकेटर वेट को डिफ़ॉल्ट तत्परता प्राइमेटिव होना चाहिए। जब निकासी को परिवर्तनों के वंश की भी आवश्यकता होती है, तो MutationObserver जोड़ें, और जब संरचित प्रतिक्रिया प्रदर्शित DOM से अधिक स्थिर हो, तो नेटवर्क कैप्चर पसंद करें।

सामान्य म्यूटेशनऑब्जर्वर विफलता तरीके

पहला घटना गायब है

अवर्डर क्रिया के बाद स्थापित किया गया था। क्लिक करने या राज्य अंतरण पर जाने से पहले इसे रजिस्टर करें।

कैप्चर बहुत बड़ा हो जाता है

एक छोटे रूट का अवलोकन करें, विशेषताओं को फ़िल्टर करें, और केवल उन क्षेत्रों को स्टोर करें जो आपके लिए आवश्यक हैं। कभी भी एक लंबे समय तक चलने वाले कैप्चर में DOM नोड को न रखें।

विशेषता परिवर्तन दोहराएँ

फ्रेमवर्क एक ही विशेषता को कई बार लिख सकते हैं। तय करें कि क्या आपको हर परिवर्तन की आवश्यकता है या केवल अंतिम मान, फिर कॉलबैक के बाहर डुप्लिकेट करें।

अवलोकक कभी नहीं रुकता

एक बार जब अपेक्षित रिकॉर्ड आ जाएं या जब कार्य की समय सीमा समाप्त हो जाए, तो इसे डिस्कनेक्ट करें। बिना अंत के अवलोकन से मेमोरी वृद्धि होती है।

निष्कर्ष

MutationObserver आपको क्लाइंट-साइड DOM परिवर्तनों के लिए वंश देता है, जबकि Playwright लोकेटर उपयोगी अंतिम स्थिति की पुष्टि करते हैं। क्रिया से पहले अवलोकक स्थापित करें, छोटे रिकॉर्ड को सीरियलाइज़ करें, केवल प्रासंगिक म्यूटेशन कक्षाओं पर ध्यान दें, और तुरंत डिस्कनेक्ट करें। कार्यप्रवाह को Scrapeless में स्थानांतरित करने से ब्राउज़र निर्माण बिना घटना कैप्चर को बदले।

क्या आप डायनामिक पृष्ठ स्थिति कैप्चर करने के लिए तैयार हैं?

Scrapeless समुदाय में ब्राउज़र-आधारित निकासी कार्यप्रवाह बनाने वाले डेवलपर्स से जुड़ें: डिस्कॉर्ड · टेलीग्राम

Scrapeless के साथ शुरुआत करें, Scrapeless मूल्य निर्धारण की समीक्षा करें, और इस कार्यप्रवाह की तुलना करें नेटवर्क अनुरोध अवरोधन के साथ जब पृष्ठ संरचित प्रतिक्रियाएँ प्रदर्शित करता है।

अक्सर पूछे जाने वाले प्रश्न

प्रश्न: क्या MutationObserver Playwright वेट्स से बेहतर है?

वे अलग-अलग प्रश्नों के उत्तर देते हैं। अवलोकक रिकॉर्ड करता है कि क्या बदला; एक लोकेटर वेट पुष्टि करता है कि आपको जो तत्व या स्थिति चाहिए वह तैयार है।

प्रश्न: मुझे अवलोकक कब स्थापित करना चाहिए?

उस क्रिया से पहले जो परिवर्तन को प्रेरित कर सकती है। इसके बाद इसे स्थापित करने पर आप केवल उस घटना को नहीं देख पाएंगे जिसकी आपको आवश्यकता थी।

प्रश्न: क्या MutationObserver नेटवर्क प्रतिक्रियाएँ देख सकता है?

नहीं। यह DOM परिवर्तनों को देखता है। नेटवर्क पेलोड की आवश्यकता होने पर अनुरोध/प्रतिक्रिया घटनाओं का उपयोग करें।

प्रश्न: क्यों देखी गई विशेषताओं को फ़िल्टर करें?

फ्रेमवर्क कई विशेषताओं को बदलते हैं। एक attributeFilter कैप्चर को सीमित और प्रासंगिक रखता है।

प्रश्न: क्या मुझे सीधे MutationRecord ऑब्जेक्ट्स को स्टोर करना चाहिए?

Copy
नहीं। उन्हें छोटे सामान्य ऑब्जेक्ट्स में परिवर्तित करें क्योंकि रिकॉर्ड DOM नोड्स का संदर्भ देते हैं और सुविधाजनक अनुक्रमित आउटपुट नहीं हैं।

**प्रश्न: मैं एक अवलोकक को कैसे रोकूं?**

अपेक्षित रिकॉर्ड आने के बाद या एक सीमित कार्य समय सीमा पर `disconnect()` कॉल करें।

**प्रश्न: क्या एक सार्वजनिक पृष्ठ का अवलोकन हमेशा अनुमति है?**

नहीं। साइट की शर्तों की समीक्षा करें, केवल आवश्यक सार्वजनिक डेटा एकत्र करें, सत्र और अनुरोध मात्रा को सीमित करें, और जहाँ लागू हो, <a href="https://datatracker.ietf.org/doc/html/rfc9309" rel="nofollow"><strong>रोबोट नीति</strong></a> का पालन करें।

स्क्रैपलेस में, हम केवल सार्वजनिक रूप से उपलब्ध डेटा का उपयोग करते हैं, जबकि लागू कानूनों, विनियमों और वेबसाइट गोपनीयता नीतियों का सख्ती से अनुपालन करते हैं। इस ब्लॉग में सामग्री केवल प्रदर्शन उद्देश्यों के लिए है और इसमें कोई अवैध या उल्लंघन करने वाली गतिविधियों को शामिल नहीं किया गया है। हम इस ब्लॉग या तृतीय-पक्ष लिंक से जानकारी के उपयोग के लिए सभी देयता को कोई गारंटी नहीं देते हैं और सभी देयता का खुलासा करते हैं। किसी भी स्क्रैपिंग गतिविधियों में संलग्न होने से पहले, अपने कानूनी सलाहकार से परामर्श करें और लक्ष्य वेबसाइट की सेवा की शर्तों की समीक्षा करें या आवश्यक अनुमतियाँ प्राप्त करें।

सबसे लोकप्रिय लेख

सूची