PixelRAG + Scrapeless: जब स्क्रीनशॉट टाइलिंग रिमोट होती है तो क्या टूटता है
Lead Scraping Automation Engineer
TL;DR:
- Visual RAG पृष्ठों को पार्स किए गए टेक्स्ट के बजाय स्क्रीनशॉट टाइल के रूप में इंडेक्स करता है, इसलिए टाइल की ज्यामिति केवल सजावटी नहीं है — यह निर्धारित करती है कि एंबेडिंग मॉडल वास्तव में क्या देखता है।
- PixelRAG का रेंडरर
Emulation.setDeviceMetricsOverrideके साथ 875 द्वारा 8192 का कैप्चर व्यूॉपर्ट सेट करता है, फिर हर स्क्रीनशॉट को 875 चौड़ा क्लिप करता है। - एक क्लाउड ब्राउज़र के खिलाफ जो रिपोर्ट में सफलता को ओवरराइट करता है और कभी भी अनुरोधित चौड़ाई लागू नहीं करता है। सत्रों के बीच परिणामस्वरूप लेआउट चौड़ाई 945 से 5120 तक वापस आती है — कभी-कभी अपरिवर्तित, आमतौर पर चौड़ी, लेकिन कभी भी 875 नहीं।
- क्लिप को बिल्कुल सम्मानित किया जाता है, जो इसे खतरनाक बनाता है: आपको एक सही आकार की टाइल मिलती है जिसमें एक पन्ने का बायाँ स्लाइस होता है जो बहुत चौड़ा बिछाया गया है।
- एक वास्तविक कैप्चर पर, एक 1920 चौड़ी लेआउट का 875 चौड़ा टाइल एक उत्पाद कॉलम रखता है जबकि पृष्ठ चार को बिछाता है, कार्ड अपने बटन के माध्यम से कटा हुआ है।
rawFilePathत्वरित मार्ग बिना किसी त्रुटि के एक दूरस्थ ब्राउज़र के खिलाफ स्वीकार किया जाता है, इसके बजाय इनलाइन डेटा लौटाता है, और कोई स्थानीय फ़ाइल नहीं लिखता है — इसलिए उस फ़ाइल को पढ़ने वाला पाइपलाइन कुछ नहीं पाता है जबकि हर कॉल सफल प्रतीत होता है।- एकल टाइल पर भरोसा करने से पहले, ओवरराइट के बाद आपको
innerWidthके खिलाफ आपके द्वारा मांगी गई चौड़ाई की तुलना करनी चाहिए। - Scrapeless मुफ्त योजना पर शुरू करें और अपनी खुद की कैप्चर ज्यामिति मापें।
Scrapeless Scraping Browser एक क्लाउड ब्राउज़र है जिसे आप एक CDP WebSocket के माध्यम से चलाते हैं, और नीचे दिए गए प्रत्येक माप उसी CDP कॉल के खिलाफ लिया गया है जो एक स्थानीय रेंडरर उपयोग करेगा।
विजुअल रिट्रीवल-ऑगमेंटेड जेनरेशन HTML पार्सिंग को छोड़ देता है। किसी पृष्ठ को पाठ में परिवर्तित करने और टुकड़ों को एंबेड करने के बजाय, यह पृष्ठ को छवियों में रेंडर करता है, छवियों को एंबेड करता है, और एक दृष्टि मॉडल को पिक्सल से उत्तर पढ़ने देता है। टेबल, चार्ट, और मल्टी-कॉलम लेआउट जीवित रहते हैं, क्योंकि कुछ भी कभी टेक्स्ट स्ट्रीम में समतल नहीं किया गया।
यह केवल तभी काम करता है जब चित्र सही हो। एक टाइलिंग रेंडरर एक विशिष्ट वादा करता है — पृष्ठ को एक निश्चित चौड़ाई पर बिछाया जाता है, फिर इसे निश्चित-ऊँचाई टाइल में काटा जाता है — और एक दृश्य सूची केवल उतनी ही अच्छी होती है जितना कि वह वादा। PixelRAG वर्तमान में सबसे स्पष्ट उदाहरण है, और इसका रेंडरर ध्यान से पढ़ने के लायक है क्योंकि जो धारणा यह बनाता है, वह हर स्क्रीनशॉट पाइपलाइन बनाती है। यह पोस्ट उस धारणा पर मापती है जो एक ब्राउज़र पर होती है जिसे आपने लॉन्च नहीं किया।
Tiling How काम करना चाहिए
PixelRAG का त्वरित रेंडरर एक WebSocket के माध्यम से कच्चा CDP बोलता है, बजाय इसके कि ड्राइवर लाइब्रेरी के माध्यम से जाए। यह render/src/pixelrag_render/backends/fast_cdp.py के शीर्ष पर दो स्थिरांक सेट करता है:
python
VIEWPORT_WIDTH = 875
TILE_HEIGHT = 8192
फिर, प्रति कार्यकर्ता एक बार, इसे कैप्चर व्यूपोर्ट के रूप में लागू करता है:
python
await conn.cdp("Emulation.setDeviceMetricsOverride", {
"width": VIEWPORT_WIDTH,
"height": tile_height,
"deviceScaleFactor": 1,
"mobile": False,
})
और प्रत्येक टाइल के लिए, यह पृष्ठ के नीचे कदम रखते हुए उसी चौड़ाई पर एक क्लिप किया हुआ आयत कैप्चर करता है:
python
await conn.cdp("Page.captureScreenshot", {
"clip": {"x": 0, "y": t * tile_height, "width": VIEWPORT_WIDTH,
"height": clip_h, "scale": 1},
})
तर्क ध्वनि और मानक है। Emulation.setDeviceMetricsOverride वह CDP कॉल है जो CSS व्यूपोर्ट विनिर्देशन अवधारणाओं के साथ हार्दिक संबंध रखता है, और यह वही है जो ड्राइवर लाइब्रेरी नीचे कॉल करती है जब आप व्यूपोर्ट सेट करते हैं। पृष्ठ को 875 पर बिछाएं, इसे 8192-ऊंचे स्ट्रिप्स में काटें, स्ट्रिप्स को एंबेड करें। एक ब्राउज़र पर जिसे आपने स्वयं लॉन्च किया है, ठीक यही होता है।
पूर्वापेक्षाएँ
- Python 3.10 या बाद का संस्करण और
websocketsपैकेज। - डैशबोर्ड से Scrapeless API कुंजी,
SCRAPELESS_KEYके रूप में निर्यातित। - कोई स्थानीय ब्राउज़र नहीं। नीचे दिए गए प्रत्येक कॉल एक WebSocket कनेक्शन के माध्यम से क्लाउड ब्राउज़र पर जाता है।
bash
pip install "websockets==15.0.1"
export SCRAPELESS_KEY="your_api_key_here"
ओवरराइट को मापें इसे स्वीकार करने के बजाय
ओवरराइट एक परिणाम वस्तु लौटाता है जिसमें कोई त्रुटि नहीं होती है, जो पूरी समस्या है — प्रतिक्रिया के बारे में कुछ भी यह सुझाव नहीं देता कि अनुरोध का सम्मान नहीं किया गया था। इसके बजाय पृष्ठ से लेआउट चौड़ाई पढ़ें।
python
import asyncio, json, os
import websockets
CDP = ("wss://browser.scrapeless.com/api/v2/browser"
f"?token={os.environ['SCRAPELESS_KEY']}&sessionTTL=120&proxyCountry=ANY")
WIDTH, HEIGHT = 875, 8192
async def call(ws, state, method, params=None, session=None):
state["id"] += 1
msg = {"id": state["id"], "method": method}
if params:
msg["params"] = params
if session:
msg["sessionId"] = session
await ws.send(json.dumps(msg))
while True:
reply = json.loads(await ws.recv())
if reply.get("id") == state["id"]:
return reply
async def one_session(run):
async with websockets.connect(CDP, max_size=50 * 1024 * 1024) as ws:
state = {"id": 0}
target = await call(ws, state, "Target.createTarget", {"url": "about:blank"})
tid = target["result"]["targetId"]
attached = await call(ws, state, "Target.attachToTarget",
{"targetId": tid, "flatten": True})
sid = attached["result"]["sessionId"]
await call(ws, state, "Page.enable", session=sid)
await call(ws, state, "Page.navigate",
{"url": "https://books.toscrape.com/"}, session=sid)
await asyncio.sleep(2.5)
async def inner_width():
r = await call(ws, state, "Runtime.evaluate",
{"expression": "innerWidth", "returnByValue": True},
session=sid)
return r["result"]["result"]["value"]
before = await inner_width()
result = await call(ws, state, "Emulation.setDeviceMetricsOverride",
{"width": WIDTH, "height": HEIGHT,
"deviceScaleFactor": 1, "mobile": False}, session=sid)
await asyncio.sleep(1)
after = await inner_width()
print(f"run{run}: error={result.get('error')} before={before} "
f"after={after} requested={WIDTH} applied={after == WIDTH}")
await call(ws, state, "Target.closeTarget", {"targetId": tid})
return after
async def main():
widths = [await one_session(run) for run in range(1, 4)]
print(f"distinct widths: {sorted(set(widths))} · requested {WIDTH} ever applied: "
f"{WIDTH in widths}")
asyncio.run(main())
text
run1: error=None before=945 after=1280 requested=875 applied=False
run2: error=None before=945 after=1600 requested=875 applied=False
run3: error=None before=945 after=945 requested=875 applied=False
distinct widths: [945, 1280, 1600] · requested 875 ever applied: False
इसे फिर से चलाएं और after कॉलम विभिन्न संख्याएँ रखता है। वह अस्थिरता परिणाम है न कि उसके चारों ओर शोर, इसलिए अंतिम पंक्ति वह है जिसे पिन करना उचित है: अनुरोधित चौड़ाई कभी भी लागू चौड़ाई नहीं होती।
यहां तीन चीजें अलग करने लायक हैं। कॉल विफल नहीं होती। जिस चौड़ाई पर यह उतरता है, वह सत्र से सत्र में भिन्न होती है — अलग-अलग रन के बीच मान 945, 1240, 1280, 1400, 1440, 1600, 1680, 1920, 2560 और 5120 के रूप में वापस आया है। और उन सत्रों में से किसी में भी वह 875 नहीं था जिसे मांगा गया था।
ऊपर रन 3 को देखें: कभी-कभी चौड़ाई बिल्कुल नहीं चलती, और 945 पहले 945 के बाद बन जाता है। इसलिए ओवरराइट विश्वसनीय रूप से एक नकारात्मक प्रतिक्रिया नहीं है और न ही विश्वसनीय रूप से कोई परिवर्तन है। एकमात्र गुण जो हर सत्र में धरा है वह उपयोगी है — संख्या जिसे आप मांगते हैं वह वह संख्या नहीं है जो आपको मिलती है।
व्यावहारिक पढ़ाई यह है कि दूरस्थ ब्राउज़र अपने अपने.window का मालिक होता है, और ओवरराइड उस.window के खिलाफ फिर से लेआउट करता है न कि आपके नंबरों के खिलाफ। स्थानीय रूप से आप प्रक्रिया का स्वामित्व रखते हैं, इसलिए वही कॉल व्यवहार करता है।
टाइल वास्तव में क्या शामिल है
अब एक टाइल को उस तरीके से कैप्चर करें जैसे एक टाइलिंग रेंडरर करता है, उस चौड़ाई पर स्पष्ट क्लिप के साथ जिसे आपने सेट करने की सोची थी।
python
import asyncio, base64, json, os, pathlib, struct
import websockets
CDP = ("wss://browser.scrapeless.com/api/v2/browser"
f"?token={os.environ['SCRAPELESS_KEY']}&sessionTTL=120&proxyCountry=ANY")
WIDTH = 875
async def call(ws, state, method, params=None, session=None):
state["id"] += 1
msg = {"id": state["id"], "method": method}
if params:
msg["params"] = params
if session:
msg["sessionId"] = session
await ws.send(json.dumps(msg))
while True:
reply = json.loads(await ws.recv())
if reply.get("id") == state["id"]:
return reply
async def main():
async with websockets.connect(CDP, max_size=100 * 1024 * 1024) as ws:
state = {"id": 0}
tid = (await call(ws, state, "Target.createTarget",
{"url": "about:blank"}))["result"]["targetId"]
sid = (await call(ws, state, "Target.attachToTarget",
{"targetId": tid, "flatten": True}))["result"]["sessionId"]
await call(ws, state, "Page.enable", session=sid)
await call(ws, state, "Page.navigate",
{"url": "https://books.toscrape.com/"}, session=sid)
await asyncio.sleep(2.5)
await call(ws, state, "Emulation.setDeviceMetricsOverride",
{"width": WIDTH, "height": 8192,
"deviceScaleFactor": 1, "mobile": False}, session=sid)
await asyncio.sleep(1)
layout = await call(ws, state, "Runtime.evaluate",
{"expression": "innerWidth", "returnByValue": True},
session=sid)
shot = await call(ws, state, "Page.captureScreenshot",
{"format": "png", "captureBeyondViewport": True,
"clip": {"x": 0, "y": 0, "width": WIDTH,
"height": 1200, "scale": 1}}, session=sid)
image = base64.b64decode(shot["result"]["data"])
png_w, png_h = struct.unpack(">II", image[16:24])
print(f"layout width: {layout['result']['result']['value']}")
print(f"tile size: {png_w}x{png_h} (requested {WIDTH}x1200)")
pathlib.Path("tile.png").write_bytes(image)
await call(ws, state, "Target.closeTarget", {"targetId": tid})
asyncio.run(main())
text
layout width: 1920
tile size: 875x1200 (requested 875x1200)
यहाँ प्रिंट की गई चौड़ाई और ऊँचाई छवि हैडर से सीधे पढ़ी गई हैं न कि अनुमानित, चूँकि PNG विनिर्देशन इसे फ़ाइल के पहले टुकड़े में रखता है। टाइल ठीक उस आकार में है जो अनुरोध किया गया था। इसके पीछे का पृष्ठ काफी चौड़ा है, और जिस चौड़ाई पर यह उतरता है वह सत्र के अनुसार बदलती है, इसलिए आप जो पृष्ठ कैप्चर करते हैं उसका अंश भी निश्चित नहीं है।
इस रन से बचाया गया tile.png दिखाता है कि इसका क्या लागत है। 1920 की लेआउट चौड़ाई पर टाइल में एक उत्पाद कॉलम होता है जहाँ पृष्ठ चार लेआउट करता है, दृश्यमान कार्ड इसके "टोकरी में जोड़ें" बटन के माध्यम से कट गया है, और शीर्षक पाठ दाहिनी किनारे से बाहर चला जाता है। पृष्ठ चौड़ाई का आधा हिस्सा छवि के बाहर है।
एक टेक्स्ट स्क्रेपर को परवाह नहीं होगी, क्योंकि यह DOM को पढ़ता है और DOM पूरा होता है। एक दृश्य सूचक को पूरी तरह से परवाह होती है: टाइल इनपुट है, और लगभग आधा पृष्ठ कभी एकीकरण मॉडल तक नहीं पहुँचता। पुनर्प्राप्ति एक भी गलती के बिना भटकती है, यही कारण है कि अनुरोधित चौड़ाई को innerWidth के खिलाफ तुलना करना हर वातावरण में एक बार करना फायदेमंद है।
क्या आप एक क्लाउड ब्राउज़र के खिलाफ अपने कैप्चर ज्यामिति की जांच करना चाहते हैं? एक मुफ्त Scrapeless खाता बनाएं और उपरोक्त दो ब्लॉकों को चलाएं।
रॉ-कैप्चर पथ गायब हो जाता है
PixelRAG की थ्रूपुट चाल यह है कि ब्राउज़र में PNG एन्कोडिंग को छोड़ दिया जाए। यह Chrome से सीधी मेमोरी में कच्चे पिक्सल फेंकने के लिए कहता है एक rawFilePath पैरामीटर के साथ, फिर उन्हें एक अलग प्रक्रिया पूल में संकुचित करता है। रिपॉजिटरी के लिए ठीक ऐसा करने के लिए एक Chromium पैच फ़ाइल शिप की जाती है, और संकुचन कार्यकर्ता फ़ाइल को open(raw_path, "rb") के साथ वापस पढ़ता है।
एक दूरस्थ ब्राउज़र के खिलाफ, उस पैरामीटर को स्वीकार किया जाता है और चुपचाप अनदेखा कर दिया जाता है।
python
import asyncio, json, os, pathlib
import websockets
CDP = ("wss://browser.scrapeless.com/api/v2/browser"
f"?token={os.environ['SCRAPELESS_KEY']}&sessionTTL=120&proxyCountry=ANY")
RAW = pathlib.Path("/dev/shm/tile_probe.raw")
async def call(ws, state, method, params=None, session=None):
state["id"] += 1
msg = {"id": state["id"], "method": method}
if params:
msg["params"] = params
if session:
msg["sessionId"] = session
await ws.send(json.dumps(msg))
while True:
reply = json.loads(await ws.recv())
if reply.get("id") == state["id"]:
return reply
async def main():
RAW.unlink(missing_ok=True)
async with websockets.connect(CDP, max_size=100 * 1024 * 1024) as ws:
state = {"id": 0}
tid = (await call(ws, state, "Target.createTarget",
{"url": "about:blank"}))["result"]["targetId"]
sid = (await call(ws, state, "Target.attachToTarget",
{"targetId": tid, "flatten": True}))["result"]["sessionId"]
await call(ws, state, "Page.enable", session=sid)
await call(ws, state, "Page.navigate",
{"url": "https://books.toscrape.com/"}, session=sid)
await asyncio.sleep(2.5)
shot = await call(ws, state, "Page.captureScreenshot",
{"fromSurface": True, "optimizeForSpeed": True,
"rawFilePath": str(RAW),
"clip": {"x": 0, "y": 0, "width": 875,
"height": 1000, "scale": 1}}, session=sid)
print("error:", shot.get("error"))
print("inline data returned:", len(shot["result"].get("data", "")))
print("local file exists:", RAW.exists())
await call(ws, state, "Target.closeTarget", {"targetId": tid})
asyncio.run(main())
text
error: None
inline data returned: 245576
local file exists: False
कोई त्रुटि नहीं, प्रतिक्रिया पर वास्तविक छवि डेटा, और डिस्क पर कुछ भी नहीं। पथ संकेत देता है: /dev/shm उस मशीन को संदर्भित करता है जो ब्राउज़र चला रहा है, और वह आपकी कोड चला रही मशीन नहीं है। एक कार्यकर्ता जो अपेक्षित फ़ाइल खोलता है FileNotFoundError हर टाइल के लिए उठाता है, और यदि उन विफलताओं को गिना जाता है न कि उठाया जाता है, तो रन रिपोर्ट करता है कि टाइलें लिखी गई हैं जबकि आउटपुट निर्देशिका खाली रहती है।
यह दो निष्कर्षों में से तेज़ है, क्योंकि यह गुणवत्ता की गिरावट नहीं है। यह एक पाइपलाइन है जो कुछ उत्पन्न नहीं करती और कहती है कि यह काम किया।
इसके बजाय क्या करें
कोई भी निष्कर्ष दूरस्थ रेंडरिंग के खिलाफ नहीं है। वे इसमें स्थानीय धारणाओं को ले जाने के खिलाफ हैं।
ज्यामिति को वापस पढ़ें न कि इसे सेट करें। ओवरराइड के बाद innerWidth वह संख्या है जिसका उपयोग आपकी टाइलिंग गणित को करना चाहिए, न कि वह संख्या जिसे आपने पास किया। यदि आपकी टाइलें उस चौड़ाई के लिए एक निश्चित चौड़ाई होनी चाहिए जिस पर एक मॉडल को प्रशिक्षित किया गया था, तो कैप्चर की गई छवि को बाद में स्केल या पैड करें न कि ब्राउज़र पर आपके नंबर पर लेआउट करने पर भरोसा करें।
कच्चे पथ पर एन्कोडेड छवि लें। rawFilePath खोने से PNG या JPEG एन्कोडिंग समय खर्च होता है और बाइट्स को आपकी प्रक्रिया में लौटाता है, जो दूरस्थ ब्राउज़र के लिए एकमात्र जगह है जहां यह उपयोगी है।
टाइल ज्यामिति को कुछ वास्तव में व्यक्त करने के रूप में मानें। अनुरोधित चौड़ाई की तुलना में मापी गई चौड़ाई की एक जांच, एक बार जब वातावरण बदलता है, इन दोनों को कैच करती है इससे पहले कि उन पर एक सूचकांक बनाया जाए। दोनों एक त्रुटि के रूप में प्रकट नहीं होते हैं, और दोनों वह देखते हैं जो मॉडल देखता है।
निष्कर्ष
स्क्रीनशॉट टाइलिंग मानती है कि रेंडरर ने सेट की गई दृश्यपट का सम्मान किया है, और एक ब्राउज़र पर जिसे आपने लॉन्च किया है वह मान्यता सुरक्षित है। एक क्लाउड ब्राउज़र पर ओवरराइड सफल होता है और लेआउट चौड़ाई कहीं और आती है - यहाँ छह विभिन्न मानों के रूप में मापी गई, उनमें से कोई भी अनुरोधित 875 नहीं है - जबकि स्क्रीनशॉट क्लिप पिक्सेल तक सम्मानित है। परिणाम गलत क्षेत्र का सही आकार का टाइल है।
कच्चे-कैप्चर पथ अधिक स्वच्छ और अधिक गंभीरता से विफल हो जाता है: स्वीकार किया गया, अनदेखा किया गया, कोई फ़ाइल नहीं, कोई त्रुटि नहीं। एक दृश्य सूचकांकीय पर विश्वास करने से पहले टाइल की गिनती और मापी गई चौड़ाई की जाँच करें, और इसे मानने के बजाय ज्यामिति को वापस पढ़ें।
प्रोटोकॉल के पीछे की गहरी जानकारी Chrome DevTools Protocol क्या है में है, कनेक्शन को Playwright और स्क्रैपिंग ब्राउज़र गाइड में कवर किया गया है, योजना विवरण Scrapeless मूल्य निर्धारण पृष्ठ पर है, और सत्र पैरामीटर Scrapeless दस्तावेज़ीकरण में हैं।
सामान्य प्रश्न
प्र: क्या इसका मतलब है कि PixelRAG क्लाउड ब्राउज़र का उपयोग नहीं कर सकता?
बिल्कुल नहीं - इसका मतलब है कि इसका रेंडरर आज एक स्थानीय को मानता है। टाइलिंग लॉजिक, एम्बेडिंग मॉडल, और अनुक्रमण अप्रभावित रहते हैं; जिसे बदलने की आवश्यकता है वह कैप्चर चरण है, जिसे लेआउट चौड़ाई को वापस पढ़ना चाहिए और कच्चे फ़ाइल पथ के बजाय एन्कोडेड-इमेज प्रतिक्रिया का उपयोग करना चाहिए।
प्र: अगर यह मेरी वैल्यू लागू नहीं करता है तो ओवरराइड चौड़ाई को क्यों बदलता है?
क्योंकि यह एक रीलाउट को ट्रिगर करता है, बस ब्राउज़र की अपनी विंडो के खिलाफ आपके अनुरोधित मैट्रिक्स के बजाय। कॉल करने से पहले चौड़ाई हर मापी गई सत्र में 945 थी और बाद में कुछ अलग, इसलिए कॉल का प्रभाव है - यह गंतव्य है जिसे चुनना आपका नहीं है।
प्र: क्या क्लिप पैरामीटर विश्वसनीय है?
हाँ, और यही वह चीज है जो असंगति को देखना आसान बनाती है। हर कैप्चर बिल्कुल अनुरोधित पिक्सेल आयाम में वापस आया। सही आउटपुट आकार इस बात का प्रमाण नहीं है कि उसके नीचे का पृष्ठ उस आकार में व्यवस्थित था।
प्र: क्या Playwright जैसी ड्राइवर लाइब्रेरी इससे बच पाएगी?
नहीं, क्योंकि ड्राइवर नीचे समान CDP कमांड जारी करता है। इस अंत बिंदु पर एक पिछले माप ने पाया कि Playwright व्यू पोर्ट सेट करने वाला रिपोर्टेड आयामों को पूरी तरह से अपरिवर्तित छोड़ देता है, इसलिए लक्षण थोड़ा भिन्न होता है जबकि कारण वही होता है। The WebDriver BiDi specification दूरस्थ ब्राउज़र नियंत्रण को एक परिभाषित अनुबंध देने के लिए मानक-ट्रैक प्रयास है, जो इस तरह के व्यवहार को अंततः निर्धारित करने का स्थान है।
प्र: मैं अपनी सेटअप को तेजी से कैसे जांचूं?
व्यू पोर्ट सेट करें, फिर innerWidth का मूल्यांकन करें और यह देखें कि आपने क्या मांगा था। एक पंक्ति, एक राउंड ट्रिप, और यह आपको तुरंत बताता है कि आपकी टाइलिंग गणित एक असली संख्या पर काम कर रही है या एक आशाजनक एक।
प्र: क्या एक फिक्स्ड-चौड़ाई क्रॉप वास्तव में पुनर्प्राप्ति को नुकसान पहुंचाता है?
यह इनपुट वितरण को बदलता है। एक एम्बेडिंग मॉडल जो एक निश्चित चौड़ाई पर व्यवस्थित पृष्ठों के स्क्रीनशॉट पर ट्यून किया गया है, इसके बजाय व्यापक लेआउट के क्रॉप प्राप्त करता है, जिसमें दाईं ओर सामग्री गायब होती है। टाइल अभी भी एम्बेड होती है और पड़ोसियों को लौटाती है, इसलिए कुछ भी टूटा हुआ नहीं दिखाई देता - परिणाम बस उन पृष्ठों पर खराब होते जाते हैं जिनकी उपयोगी सामग्री क्रॉप के बाहर होती है।
प्र: टाइलिंग रन के लिए sessionTTL क्या होना चाहिए?
इतना लंबा कि पूरे पृष्ठ को कवर कर सके, क्योंकि टाइलिंग अनुक्रमिक होती है और एक लंबा पृष्ठ एक सत्र में कई कैप्चर की आवश्यकता होती है। इसे आपके धीमे से अपेक्षित पृष्ठ के खिलाफ आकार दें बजाय कि औसत पृष्ठ के, और जब रन समाप्त हो जाए तो लक्ष्य को बंद कर दें।
स्क्रैपलेस में, हम केवल सार्वजनिक रूप से उपलब्ध डेटा का उपयोग करते हैं, जबकि लागू कानूनों, विनियमों और वेबसाइट गोपनीयता नीतियों का सख्ती से अनुपालन करते हैं। इस ब्लॉग में सामग्री केवल प्रदर्शन उद्देश्यों के लिए है और इसमें कोई अवैध या उल्लंघन करने वाली गतिविधियों को शामिल नहीं किया गया है। हम इस ब्लॉग या तृतीय-पक्ष लिंक से जानकारी के उपयोग के लिए सभी देयता को कोई गारंटी नहीं देते हैं और सभी देयता का खुलासा करते हैं। किसी भी स्क्रैपिंग गतिविधियों में संलग्न होने से पहले, अपने कानूनी सलाहकार से परामर्श करें और लक्ष्य वेबसाइट की सेवा की शर्तों की समीक्षा करें या आवश्यक अनुमतियाँ प्राप्त करें।


