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

IndexedDB डेटा को Playwright और Scrapeless के साथ कैसे निकालें

Sophia Martinez
Sophia Martinez

Specialist in Anti-Bot Strategies

30-Jul-2026

TL;DR:

  • IndexedDB में संरचित ब्राउज़र डेटा हो सकता है जो प्रारंभिक HTML में कभी नहीं दिखाई देता। इसे पढ़ने के लिए पृष्ठ की उत्पत्ति के अंदर कोड चलाना आवश्यक है जब अनुप्रयोग अपने डेटाबेस को खोलता है।
  • IndexedDB निकालने की प्रक्रिया डेटाबेस और स्कीमा खोज से शुरू होनी चाहिए। रिकॉर्ड पढ़ने से पहले डेटाबेस, ऑब्जेक्ट स्टोर्स और इंडेक्स की सूची बनाएं, नामों का अनुमान लगाने के बजाय।
  • Playwright IndexedDB के कॉल बैक-आधारित अनुरोधों को एक वेटेबल निकासी वर्कफ़्लो में जोड़ सकता है। अनुरोधों जैसे indexedDB.open() और getAll() को page.evaluate() के अंदर प्रॉमिस में लपेटें।
  • रेंडर्ड DOM और IndexedDB एक ही एप्लिकेशन स्थिति के विभिन्न उपसमुच्चय प्रकट कर सकते हैं। फ़िल्टरिंग, पेजिनेशन, या पुराने UI डेटा का पता लगाने के लिए दोनों गिनतियों को संरक्षित करें।
  • बड़े या संवेदनशील स्टोर्स को सीमित निकासी की आवश्यकता होती है। अनियंत्रित getAll() कॉल के बजाय कुंजी रेंज, गिनतियों या कर्सर का उपयोग करें, और केवल अधिकृत ब्राउज़र सत्रों की जांच करें।
  • वही IndexedDB क्वेरी स्थानीय रूप से और Scrapeless के माध्यम से काम करती है। Scrapeless Scraping Browser में जाना ब्राउज़र निर्माण को बदलता है, पृष्ठ-साइड डेटाबेस लॉजिक को नहीं।
  • शुरू करने के लिए स्वतंत्र। नए Scrapeless खाते में मुफ्त Scraping Browser रनटाइम शामिल है—app.scrapeless.com पर साइन अप करें।

परिचय: ब्राउज़र डेटा DOM के साथ समाप्त नहीं होता

IndexedDB संरचित रिकॉर्ड रख सकता है जो किसी पृष्ठ के प्रारंभिक HTML में कभी नहीं दिखाई देते। यह गाइड Playwright का उपयोग करके एक वास्तविक सार्वजनिक डेटाबेस की गणना करने, इसके ऑब्जेक्ट स्टोर और इंडेक्स का निरीक्षण करने, सभी रिकॉर्ड पढ़ने और उन्हें प्रस्तुत तालिका के साथ तुलना करने के लिए है, और फिर उसी निकासी को Scrapeless Scraping Browser में ले जाना है।

IndexedDB वेब निकाशी में क्या जोड़ता है

IndexedDB एक असिंक्रोनस, उत्पत्ति-स्कोप वाला डेटाबेस है जो ब्राउज़र में निर्मित है। स्थानीय संग्रहण के स्ट्रिंग मैप के विपरीत, यह ऑब्जेक्ट स्टोर्स में संरचित JavaScript मानों को संग्रहीत करता है और इंडेक्स, कुंजी, और लेन-देन का समर्थन करता है। MDN का IndexedDB गाइड उस मॉडल का वर्णन करता है।

अनुप्रयोग इसका उपयोग ऑफ़लाइन रिकॉर्ड, कैश किए गए API डेटा, कतारों, और ऐसे स्थिति के लिए करते हैं जो वेब स्टोरेज के लिए बहुत बड़े या संरचित हो सकते हैं। एक ब्राउज़र निकासीकर्ता सार्वजनिक एप्लिकेशन स्थिति को पढ़ सकता है जब पृष्ठ ने अपने डेटाबेस को खोला हो। यह पहुंच निजी उपयोगकर्ता डेटाबेस को उपयुक्त संग्रहण लक्ष्यों में बदल नहीं करती है; यह ट्यूटोरियल केवल MDN के सार्वजनिक संपर्क फ़िक्स्चर का उपयोग करता है।

Scrapeless के साथ Playwright का उपयोग करने के कारण

Playwright एक असिंक्रोनस फ़ंक्शन का मूल्यांकन करता है पृष्ठ की उत्पत्ति में, ताकि फ़ंक्शन indexedDB.open को कॉल कर सके, अनुरोध कॉल बैक का इंतजार कर सके, और सीधे Python को सामान्य डेटा लौटा सके। Scrapeless Scraping Browser उस पृष्ठ-साइड API को एक होस्टेड क्रोमियम सत्र के अंदर रखता है।

Playwright connect_over_cdp के माध्यम से कनेक्ट करता है। एक बार लक्ष्य पृष्ठ लोड हो जाने पर, IndexedDB क्वेरी अपरिवर्तित रहती है।

पूर्वापेक्षाएँ

  • 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 Scraping Browser से कनेक्ट करें

नोट: यह कनेक्शन वित्तपोषित Scraping Browser बैलेंस की आवश्यकता है। अंतिम सत्यापन खाते ने अपर्याप्त बैलेंस, कृपया पहले रिचार्ज करें लौटाया। नीचे दिया गया पूर्ण IndexedDB निकासी स्थानीय 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]
    # नीचे दिए गए IndexedDB क्वेरी का नेविगेट और मूल्यांकन करें।
    browser.close()

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

चरण 1 — उत्पत्ति के डेटाबेस खोजें

MDN का सार्वजनिक IDBIndex उदाहरण लोड के बाद एक डेटाबेस बनाता है:

python Copy
TARGET_URL = (
    "https://mdn.github.io/dom-examples/"
    "indexeddb-examples/idbindex/"
)

page.goto(TARGET_URL, wait_until="domcontentloaded")
page.wait_for_selector("tbody tr")
databases = page.evaluate("indexedDB.databases()")
print("databases:", databases)
text Copy
databases: [{'name': 'contactsList', 'version': 1}]

indexedDB.databases() को IDBFactory डेटाबेस संदर्भ द्वारा वर्णित किया गया है। इसे पुराने इंजनों में भरोसा करने से पहले ब्राउज़र समर्थन की जांच करें।

चरण 2 — ऑब्जेक्ट स्टोर और इंडेक्स का निरीक्षण करें

खोजे गए डेटाबेस को खोलें और स्कीमा मेटाडेटा लौटाएं:

python Copy
schema = page.evaluate("""async () => {
    const opened = await new Promise((resolve, reject) => {
        const request = indexedDB.open('contactsList');
        request.onsuccess = () => resolve(request.result);
        request.onerror = () => reject(request.error);
    });
    const storeName = opened.objectStoreNames[0];
    const transaction = opened.transaction(storeName, 'readonly');
    const store = transaction.objectStore(storeName);
    const result = {
        storeName,
        indexes: Array.from(store.indexNames),
    };
    opened.close();
    return result;
}""")

print("ऑब्जेक्ट स्टोर:", schema["storeName"])
print("इंडेक्स:", schema["indexes"])
text Copy
ऑब्जेक्ट स्टोर: contactsList
इंडेक्स: ['age', 'company', 'eMail', 'fName', 'jTitle', 'lName', 'phone']

यह फिक्स्चर contactsList का उपयोग डेटाबेस और इसके एकमात्र ऑब्जेक्ट स्टोर के लिए करता है। दोनों को सूचीबद्ध करना अभी भी महत्वपूर्ण है: बहुत सारे अनुप्रयोग विभिन्न नामों का उपयोग करते हैं, और यह मान लेना कि वे मेल खाते हैं गलत स्टोर को लक्षित कर सकता है।

चरण 3 — ऑब्जेक्ट स्टोर से रिकॉर्ड पढ़ें

IDBObjectStore.getAll() एक अनुरोध लौटाता है, न कि एक प्रॉमिस। इसके सफलता/त्रुटि कॉलबैक को लपेटें ताकि प्लेवाईट उसे प्रतीक्षा कर सके:

python Copy
records = page.evaluate("""async () => {
    const database = await new Promise((resolve, reject) => {
        const request = indexedDB.open('contactsList');
        request.onsuccess = () => resolve(request.result);
        request.onerror = () => reject(request.error);
    });
    const transaction = database.transaction('contactsList', 'readonly');
    const store = transaction.objectStore('contactsList');
    const rows = await new Promise((resolve, reject) => {
        const request = store.getAll();
        request.onsuccess = () => resolve(request.result);
        request.onerror = () => reject(request.error);
    });
    database.close();
    return rows;
}""")

print("रिकॉर्ड की संख्या:", len(records))
print("पहला:", records[0])
print("आखिरी:", records[-1])

getAll संदर्भ में उल्लेख किया गया है कि यह सभी रिकॉर्ड लौटाता है जब कोई क्वेरी या संख्या प्रदान नहीं की जाती है। वास्तविक अनुप्रयोगों में पढ़ाई को सीमित रखें; बड़े स्टोर्स के लिए एक कर्सर या संख्या अधिक सुरक्षित है।

चरण 4 — इंडेक्स्डDB की तुलना प्रदर्शित DOM से करें

python Copy
table_rows = page.locator("tbody tr").count()
arkham_rows = [row for row in records if row["company"] == "Arkham"]
ages = [row["age"] for row in records]

print("टेबल पंक्तियाँ:", table_rows)
print("डेटाबेस पंक्तियाँ:", len(records))
print("आर्कम पंक्तियाँ:", len(arkham_rows))
print("उम्र की सीमा:", min(ages), max(ages))
text Copy
टेबल पंक्तियाँ: 10
डेटाबेस पंक्तियाँ: 10
आर्कम पंक्तियाँ: 2
उम्र की सीमा: 24 55

मेल खाते संकेत证明 करते हैं कि इस फिक्स्चर ने पूरा डेटाबेस प्रदर्शित किया। एक अलग अनुप्रयोग केवल वर्तमान पृष्ठ या एक फ़िल्टर की गई उपसैट को प्रदर्शित कर सकता है, इसलिए दोनों संख्याओं को बनाए रखें बजाय यह मजबूर करने के कि वे समान हों।

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

पूर्ण कार्यशील एक्सट्रैक्टर

python Copy
from playwright.sync_api import sync_playwright

TARGET_URL = (
    "https://mdn.github.io/dom-examples/"
    "indexeddb-examples/idbindex/"
)

QUERY = """async () => {
    const databases = await indexedDB.databases();
    const database = await new Promise((resolve, reject) => {
        const request = indexedDB.open('contactsList');
        request.onsuccess = () => resolve(request.result);
        request.onerror = () => reject(request.error);
    });
    const storeName = database.objectStoreNames[0];
    const transaction = database.transaction(storeName, 'readonly');
    const store = transaction.objectStore(storeName);
    const indexes = Array.from(store.indexNames);
    const rows = await new Promise((resolve, reject) => {
        const request = store.getAll();
        request.onsuccess = () => resolve(request.result);
        request.onerror = () => reject(request.error);
    });
    database.close();
    return {databases, storeName, indexes, rows};
}"""

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")
    page.wait_for_selector("tbody tr")

    result = page.evaluate(QUERY)
    rows = result["rows"]
    table_rows = page.locator("tbody tr").count()

Here is the translation of the provided text to Hindi:

Copy
arkham_rows = [row for row in rows if row["company"] == "Arkham"]
ages = [row["age"] for row in rows]

assert result["databases"] == [{"name": "contactsList", "version": 1}]
assert result["storeName"] == "contactsList"
assert len(result["indexes"]) == 7
assert len(rows) == table_rows == 10
assert len(arkham_rows) == 2

print("शीर्षक:", page.title())
print("डेटाबेस:", result["databases"])
print("ऑब्जेक्ट स्टोर:", result["storeName"])
print("इंडेक्स:", result["indexes"])
print("डेटाबेस पंक्तियाँ:", len(rows))
print("तालिका पंक्तियाँ:", table_rows)
print("पहला संपर्क:", rows[0]["fName"], rows[0]["lName"])
print("आखिरी संपर्क:", rows[-1]["fName"], rows[-1]["lName"])
print("आर्कम पंक्तियाँ:", len(arkham_rows))
print("उम्र का दायरा:", min(ages), max(ages))
browser.close()

लाइव परिणाम में एक संस्करण-1 डेटाबेस, एक contactsList स्टोर, सात इंडेक्स, दस डेटाबेस रिकॉर्ड, दस रेंडर की गई पंक्तियाँ, दो आर्कम संपर्क, और 24 से 55 तक की उम्र है।

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

पूर्ण एक्स्ट्रैक्टर डेटाबेस की पहचान, स्कीमा मेटाडेटा, संग्रहीत रिकॉर्ड, और उसी ब्राउज़र सत्र से DOM तुलना लौटाता है:

json Copy
{
  "database": {
    "name": "contactsList",
    "version": 1
  },
  "object_store": "contactsList",
  "index_count": 7,
  "database_rows": 10,
  "rendered_rows": 10,
  "matching_company_rows": 2,
  "age_range": {
    "minimum": 24,
    "maximum": 55
  }
}

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

सामान्य IndexedDB एक्सट्रैक्शन समस्याएं

डेटाबेस सूची खाली है

ऐप्लिकेशन का डेटाबेस खोलने या बनाने का इंतज़ार करें। नेविगेशन के तुरंत बाद एक खाली सूची समय की समस्या, असमर्थित खोज एपीआई, या गलत मूल को संकेत दे सकती है।

ऑब्जेक्ट स्टोर बड़ा है

अनबाउंड स्टोर पर बिना सीमा के getAll() को कॉल न करें। एक कुंजी रेंज, गिनती, या कर्सर का उपयोग करें और अपने कार्य की आवश्यकता के अनुसार डेटा सेट के स्लाइस के बाद रुकें।

मानों में गैर-JSON प्रकार शामिल हैं

प्लेयराइट समर्थित मानों को वापस पाइथन में अनुक्रमित करता है। ब्लॉब्स, जटिल श्रेणी उदाहरण, और चक्रीय संरचनाओं को अनुक्रमित कार्य की भिन्नता के अंदर फील्ड-स्तर मैपिंग की आवश्यकता हो सकती है।

पृष्ठ और डेटाबेस असहमत हैं

पृष्ठ फ़िल्टर किया जा सकता है, पेजिनेटेड हो सकता है, या पुराना हो सकता है। डेटाबेस की पहचान, ऑब्जेक्ट-स्टोर का नाम, पृष्ठ यूआरएल, और निष्कर्षण समय को संग्रहीत करें ताकि मिलान न होने का पता लगाया जा सके।

सुरक्षित एक्सट्रैक्शन सीमाएँ

IndexedDB अक्सर निजी ऑफ़लाइन ऐप्लिकेशन डेटा शामिल करता है। इस तकनीक का उपयोग केवल उन सिस्टमों और सत्रों पर करें जिन्हें आप निरीक्षण करने के लिए अधिकृत हैं। प्रमाणपत्र, संदेश, या व्यक्तिगत रिकॉर्ड प्रकाशित न करें। सार्वजनिक MDN संपर्क कृत्रिम फ़िक्स्चर डेटा हैं।

निष्कर्ष

IndexedDB एक्सट्रैक्शन खोज और स्कीमा निरीक्षण से शुरू होता है, एक अनुमानित स्टोर नाम से नहीं। मूल के डेटाबेस को खोलें, स्टोर्स और इंडेक्स को गिनें, अनुरोध callbacks को एक प्रोमिस में ब्रिज करें, और परिणाम का सत्यापन करें जहाँ एक दृश्य सतह मौजूद हो। वर्कफ़्लो को Scrapeless में ले जाने से ब्राउज़र निर्माण में परिवर्तन आता है जबकि पृष्ठ-साइड क्वेरी को बनाए रखता है।

क्या आप संरचित ब्राउज़र स्थिति निकालने के लिए तैयार हैं?

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

Scrapeless के साथ शुरू करें, Scrapeless मूल्य निर्धारण की समीक्षा करें, और क्या CDP दर्शाता है पढ़ें इससे पहले कि वही IndexedDB कार्यप्रणाली को एक होस्ट किए गए ब्राउज़र में स्थानांतरित करें।

सामान्य प्रश्न

प्रश्न: क्या प्लेयराइट IndexedDB पढ़ सकता है?

हाँ। पृष्ठ मूल में एक असिंक्रोनस फ़ंक्शन का मूल्यांकन करें और IndexedDB अनुरोध callbacks को प्रोमिस में लपेटें।

प्रश्न: पहले डेटाबेस को क्यों गिनें?

यह नाम या संस्करण को मानने से पहले मूल और डेटाबेस की पहचान की पुष्टि करता है। सभी ब्राउज़र indexedDB.databases() को उजागर नहीं करते, इसलिए जब संगतता इसकी आवश्यकता हो तो ज्ञात-नाम बैकफॉल रखें।

प्रश्न: क्या ऑब्जेक्ट स्टोर को डेटाबेस के समान माना जाता है?

नहीं। एक डेटाबेस में एक या अधिक ऑब्जेक्ट स्टोर्स होते हैं। MDN फ़िक्स्चर में, डेटाबेस और इसका ऑब्जेक्ट स्टोर दोनों का नाम contactsList है।

प्रश्न: मैं getAll के बजाय कर्सर का उपयोग कब करूँ?

जब एक स्टोर बड़ा हो सकता है, जब आपको क्रमबद्धता की आवश्यकता हो, या जब आप एक छोटे उपसमुच्चय के बाद रुक सकते हों, तो कर्सर या बाउंडेड क्वेरी का उपयोग करें।

प्रश्न: IndexedDB पंक्तियों की तुलना DOM से क्यों करें?

तुलना यह प्रकट करती है कि UI हर रिकॉर्ड दिखाता है, एक फ़िल्टर किया गया दृश्य, या केवल एक पृष्ठ। कोई भी सतह दूसरी को चुपचाप ओवरराइट नहीं करनी चाहिए।

Copy
**प्रश्न: क्या IndexedDB ब्राउज़र सत्रों में स्थायी रहती है?**

यह एक संचित ब्राउज़र प्रोफ़ाइल में तब तक स्थायी रह सकती है जब तक कि स्रोत या ब्राउज़र इसे साफ़ नहीं करता। एक अस्थायी संदर्भ संदर्भ बंद होने पर गायब हो सकता है।

**प्रश्न: क्या IndexedDB डेटा निकालना हमेशा अनुमति है?**

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

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

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

सूची