क्लॉड वेब स्क्रैपिंग: नल होने योग्य सांख्यिकी तालिकाओं को साफ़ JSON में बदलें
Specialist in Anti-Bot Strategies
TL;DR:
- Claude नल डेटा को साफ तरीके से पढ़ता है, और एक लाइव रन इसे साबित करता है। एक प्रदर्शित सीजन-स्टैट्स टेबल को देकर,
anthropic/claude-haiku-4.5ने एक कॉल में 25 टीम-सीजन रिकॉर्ड returned किए, सही ढंग से 1990-91 NHL सीजन में मौजूद नहीं होने वाले स्टैट के लिएnullलिखते हुए, एक मूल्य का अनुमान लगाने के बजाय। - API टेक्स्ट-इन, टेक्स्ट-आउट है - यह कभी भी नेटवर्क को छूता नहीं है। रेंडरिंग, सत्र, और संपादन चुनौतियाँ एक फेच लेयर से संबंधित हैं; इस गाइड का एक पोस्ट प्रति पृष्ठ है Scrapeless Universal Scraping API के माध्यम से।
- JSON मोड में एक वास्तविक विचित्रता है जो जानना जरूरी है इससे पहले कि यह आपको एक पार्स त्रुटि का खर्च उठाए। Claude OpenRouter के माध्यम से कभी-कभी संरचित आउटपुट को
```jsonफेंस में लपेटता है भले हीresponse_formatसेट किया गया हो - नीचे दिया गया निष्कर्ष स्क्रिप्ट इसे बचावात्मक तरीके से हटा देती है। - वर्तमान सस्ते-स्तरीय नामकरण मूव्स। लाइव OpenRouter मॉडल कैटलॉग में
claude-haiku-4.5क्षमताओं में पुरानेclaude-3-haikuलाइन से काफी ऊपर है एक मामूली प्रति-टोकन प्रीमियम पर; इस गाइड ने सीधे कैटलॉग को जांचा न कि याद से नाम का अनुमान लगाएं। - क्या अभी तक कोई Anthropic कुंजी नहीं है? समान अनुरोध OpenRouter के माध्यम से चलता है। इस गाइड ने इसे
anthropic/claude-haiku-4.5पर लाइव चलाया और कैप्चर की गई आउटपुट को दिखाता है। - फेच साइड पर शुरू करने के लिए मुक्त। app.scrapeless.com पर अपना Scrapeless API कुंजी बनाएं।
क्या Claude वेबसाइटों को स्क्रैप कर सकता है?
Claude पार्स करता है; यह फ़ेच नहीं करता। इसे पृष्ठ का टेक्स्ट और एक स्कीमा दें और यह साफ, टाइप किए गए रिकॉर्ड लौटाता है - जिसमें यह जानना भी शामिल है कि कब एक फ़ील्ड वास्तव में अनुपस्थित है बजाय इसके कि कोई संभावित दिखने वाला शून्य आविष्कार करें। जो इसे नहीं कर सकता है वह एक विशिष्ट URL को पुनः प्राप्त करना, उस पृष्ठ को बनाने वाली जावास्क्रिप्ट को चलाना, एक सत्र धारण करना, या एक एक्सेस चुनौती को उस मात्रा में साफ करना है जिसकी एक स्क्रैपिंग नौकरी को आवश्यकता होती है। हर काम करने वाला "Claude वेब स्क्रैपिंग" सेटअप उस मॉडल को एक फ़ेच लेयर के साथ जोड़ता है जो इसे अलग से करता है।
इस साइट पर एक पूर्व गाइड, Claude AI के साथ वेब स्क्रैपिंग, Claude को स्क्रैपर के साथ जोड़ने के दस अलग तरीके की समीक्षा करता है। यह गाइड संकीर्ण और अधिक ठोस है: एक असली लक्ष्य, एक लाइव-निष्पादित निष्कर्षण, एक स्कीमा, वास्तविक कैप्चर की गई आउटपुट। यदि व्यापक प्रश्न यह है कि पार्सिंग के लिए किस भाषा मॉडल का उपयोग करना है, तो LLM स्क्रैपर व्याख्याता श्रेणी को कवर करता है।
इंस्टॉल
Anthropic SDK मूल पथ को कवर करता है, openai OpenRouter पथ को कवर करता है, और requests फेच लेयर को कवर करता है:
bash
pip install "anthropic==0.120.0" "openai==2.48.0" requests
कॉन्फ़िगर करें
bash
export ANTHROPIC_API_KEY="sk-ant-your_key"
export SCRAPELESS_API_KEY="sk_your_scrapeless_key"
कभी-कभी अनुपस्थित फ़ील्ड के साथ एक पृष्ठ फेच करें
डेमो लक्ष्य एक सार्वजनिक खेल-सांख्यिकी सैंडबॉक्स है: प्रत्येक NHL टीम के लिए एक सीजन-दर-सीजन पंक्ति, जिसमें एक स्टैट - ओवरटाइम हानि - शामिल है, जिसे लीग ने 1990 के मध्य तक ट्रैक नहीं किया। उस बिंदु से पहले की पंक्तियाँ सेल को खाली छोड़ देती हैं, जिससे पृष्ठ यह सुनिश्चित करने का एक वास्तविक परीक्षण बनता है कि एक एक्सट्रेक्टर डेटा का आविष्कार करता है या इसे अनुपस्थित की रिपोर्ट करता है। Universal Scraping API को एक पोस्ट पृष्ठ पर लाने के लिए रेंडरिंग और प्रॉक्सी रूटिंग सर्वर-साइड द्वारा प्रबंधित होती है:
python
# fetch_teams.py — Scrapeless के माध्यम से टीम-स्टैट्स पृष्ठ पुनः प्राप्त करें
import os
import requests
resp = requests.post(
"https://api.scrapeless.com/api/v2/unlocker/request",
headers={
"Content-Type": "application/json",
"x-api-token": os.environ["SCRAPELESS_API_KEY"],
},
json={
"actor": "unlocker.webunlocker",
"input": {"url": "https://scrapethissite.com/pages/forms/", "method": "GET", "js_render": True},
},
timeout=120,
)
resp.raise_for_status()
html = resp.json().get("data", "")
print(f"फेच किया गया {len(html):,} वर्ण")
print("टीम पंक्तियाँ:", html.count('<tr class="team">'))
with open("page.html", "w", encoding="utf-8") as f:
f.write(html)
चलाने पर यह सैंडबॉक्स के पहले पृष्ठ के लिए 25 टीम पंक्तियाँ प्रिंट करता है - एक जीवित लक्ष्य जो एक सार्वजनिक वेब-सक्रैपिंग प्रैक्टिस साइट द्वारा बनाए रखा गया है, जो इस साइट के अन्य LLM-पार्सिंग गाइड में उपयोग किए गए उद्धरणों और पुस्तकों के सैंडबॉक्स से अलग है।
बुनियादी कार्यान्वयन: एक्सट्रेक्टर के रूप में Claude
नैटिव मेसेजेज एपीआई output_config के माध्यम से सीधे JSON स्कीमा को लेता है, जिसे वर्तमान API संदर्भ में पुराने प्रीफिल-आधारित JSON ट्रिक्स के प्रतिस्थापन के रूप में दस्तावेजित किया गया है - Anthropic के संरचित-आउटपुट्स गाइड देखें। वर्तमान में सबसे सस्ता गैर-लीजेंसी क्लॉड स्तर claude-haiku-4-5 है; ध्यान दें कि नैटिव मॉडल आईडी में हाइफेन का उपयोग होता है, जो OpenRouter द्वारा सूचीबद्ध claude-haiku-4.5 स्लग से अलग है।
नोट: इस खंड को क्रेडिट के साथ
ANTHROPIC_API_KEYकी आवश्यकता है - यह एकमात्र पूर्वापेक्षा है जो इस गाइड में नहीं मानी गई है। अगला खंड OpenRouter के माध्यम से समान निष्कर्षण को वास्तविक समय में चलाता है, जिसमें कैप्चर किया गया आउटपुट होता है।
python
# extract_claude.py — नैटिव क्लॉड निष्कर्षण (ANTHROPIC_API_KEY की आवश्यकता)
import json
from anthropic import Anthropic
client = Anthropic() # पर्यावरण से ANTHROPIC_API_KEY पढ़ता है
page_html = open("page.html", encoding="utf-8").read()
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=6000,
system="इस तालिका से प्रत्येक टीम-सीजन पंक्ति निकालें। जब सेल खाली हो तो ot_losses शून्य है।",
messages=[{"role": "user", "content": page_html}],
output_config={
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"teams": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"year": {"type": "integer"},
"wins": {"type": "integer"},
"losses": {"type": "integer"},
"ot_losses": {"type": ["integer", "null"]},
"win_pct": {"type": "number"},
"goals_for": {"type": "integer"},
"goals_against": {"type": "integer"},
},
"required": ["name", "year", "wins", "losses", "ot_losses", "win_pct", "goals_for", "goals_against"],
"additionalProperties": False,
},
}
},
"required": ["teams"],
"additionalProperties": False,
},
}
},
)
text = next(b.text for b in response.content if b.type == "text")
data = json.loads(text)
print(f"निकाली गई {len(data['teams'])} टीमें")
output_config.format पुष्टि करता है कि प्रतिक्रिया स्कीमा के खिलाफ JSON के रूप में पार्स होती है - कोई फेंस-स्ट्रिपिंग नहीं, कोई प्रीफिल वर्कअराउंड नहीं।
कोई एंथ्रोपिक कुंजी नहीं? इसे OpenRouter के माध्यम से चलाएँ
OpenRouter क्लॉड को एक OpenAI-संगत चैट-पूर्णता सतह के पीछे उजागर करता है। यह वह संस्करण है जिसे इस गाइड ने वास्तविक समय में निष्पादित किया, एक आत्म-निहित स्क्रिप्ट में फेच और निष्कर्षण:
python
# extract_openrouter.py — OpenRouter के माध्यम से निष्पादित समान निष्कर्षण
import json
import os
import requests
from openai import OpenAI
resp = requests.post(
"https://api.scrapeless.com/api/v2/unlocker/request",
headers={
"Content-Type": "application/json",
"x-api-token": os.environ["SCRAPELESS_API_KEY"],
},
json={
"actor": "unlocker.webunlocker",
"input": {"url": "https://scrapethissite.com/pages/forms/", "method": "GET", "js_render": True},
},
timeout=120,
)
resp.raise_for_status()
page_html = resp.json().get("data", "")
client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key=os.environ["OPENROUTER_API_KEY"])
completion = client.chat.completions.create(
model="anthropic/claude-haiku-4.5",
temperature=0,
max_tokens=6000,
response_format={"type": "json_object"},
messages=[
{
"role": "system",
"content": 'इस तालिका से प्रत्येक टीम-सीजन पंक्ति निकालें। केवल JSON के साथ उत्तर दें: '
'{"teams":[{"name":str,"year":int,"wins":int,"losses":int,"ot_losses":int|null,'
'"win_pct":number,"goals_for":int,"goals_against":int}]}. '
"ot_losses तब शून्य होता है जब सेल खाली हो।",
},
{"role": "user", "content": page_html},
],
)
raw = completion.choices[0].message.content.strip()
if raw.startswith("```"):
raw = raw.split("```")[1]
if raw.startswith("json"):
raw = raw[4:]
data = json.loads(raw)
print(f"निकाली गई {len(data['teams'])} टीमें")
print(json.dumps(data["teams"][0], ensure_ascii=False))
सीधे चलाने से सभी 25 टीम-सीजन खींचे गए, पहला रिकॉर्ड:
text
निकाली गई 25 टीमें
{"name": "Boston Bruins", "year": 1990, "wins": 44, "losses": 24, "ot_losses": null, "win_pct": 0.55, "goals_for": 299, "goals_against": 264}
ot_losses null के लिए वापस आया 1990-91 के सीजन के लिए — यह वर्ष NHL द्वारा उस सांख्यिकी को ट्रैक करने से पहले का है — और 25 में से हर एक पंक्ति ने बिना किसी पश्च-होक कैस्टिंग के घोषित प्रकारों में पार्स किया। यहाँ बाड़ कटाई का महत्व है: इसके बिना, json.loads इस मॉडल के OpenRouter आउटपुट पर सीधे असफल हो जाता है, भले ही response_format सेट किया गया हो। पूरा कॉल: 13,365 टोकन।
मुफ्त योजना पर अपना API कुंजी प्राप्त करें: app.scrapeless.com
उन्नत पैटर्न
- एग्रीगेटर पथ पर बाड़ वाले आउटपुट के खिलाफ रक्षा करें। मूल
output_config.formatपथ बिना किसी बाड़ के स्कीमा-विशिष्ट JSON को लागू करता है; OpenRouter चैट-पूरक पथ उस एक ही गारंटी को मॉडल से मॉडल तक नहीं बनाता है, इसलिए किसी भी मॉडल को रूट करने से पहले पार्सिंग से पहले एक अग्रणी```ब्लॉक को हटा दें। - नलता को स्पष्ट रूप से नामित करें। स्कीमा अकेले (
"ot_losses": {"type": ["integer", "null"]}) और सिस्टम प्रांप्ट में एक वाक्य सही नल उत्पादन करता है इसके बजाय कि मॉडल0का आविष्कार करे। किसी एक को छोड़ दें और क्षेत्र पर भरोसा करने से पहले दोबारा परीक्षण करें। - प्रत्येक कॉल के लिए एक पृष्ठ रखें। पृष्ठ की सीमाएँ स्वाभाविक रिकॉर्ड सीमाएँ होती हैं; कई पृष्ठों को एक प्रांप्ट में बंडल करना यह धुंधला करता है कि एक टीम के आँकड़े कहाँ समाप्त होते हैं और अगली शुरू होती है।
- स्केलिंग करने से पहले टोकन मापें। ऊपर वाला रन 25-पंक्ति पृष्ठ के लिए 13,365 टोकन में लागत आया — वास्तविक पृष्ठ और क्षेत्र की गिनती को गुणा करें इससे पहले कि आप पृष्ठ मात्रा के लिए प्रतिबद्ध हों, बिल आने के बाद नहीं।
समस्या निवारण
- OpenRouter प्रतिक्रिया पर
json.loadsअसफल होता है भले ही JSON मोड सेट किया गया हो। अग्रणी```jsonबाड़ के लिए जाँच करें और पार्सिंग से पहले इसे हटा दें — इस गाइड के लाइव रन ने ठीक वही फिक्स आवश्यक था। - एक क्षेत्र जो कभी-कभी गायब होना चाहिए वह हमेशा
0या एक प्लेसहोल्डर के रूप में वापस आता है। स्कीमा और प्रांप्ट में स्पष्ट रूप से बताएं कि एक क्षेत्र नल है और कौन सी स्थिति इसे नल बनाती है; मॉडल खाली स्थान को भरने के लिए डिफ़ॉल्ट होते हैं जब तक कि उन्हें ऐसा करने के लिए न कहा जाए। - एक पृष्ठ से शून्य या कुछ पंक्तियाँ जो दर्जनों हैं। सबसे पहले प्राप्त HTML गिनती की जाँच करें, जिस तरह ऊपर का फेच स्क्रिप्ट करता है — एक पतली फेच एक रेंडरिंग या पहुँच समस्या है, जो कि निकासी प्रांप्ट ठीक नहीं कर सकता।
- पहचाने जाने वाले रन के बीच आउटपुट में परिवर्तन। OpenRouter पथ पर
temperature=0सेट करें;Extraction एक ट्रांसक्रिप्शन कार्य है, और शून्य से ऊपर कोई भी तापमान बदलने का निमंत्रण देता है।
निष्कर्ष
Claude का संरचित-आउटपुट पथ टाइपेड JSON प्राप्त करने से अनुमान लगाने वाली प्रक्रिया को हटा देता है — मूल API पर output_config.format पूरी तरह से प्रीफिल चालों को छोड़ता है, और यहां तक कि अधिक उदार OpenRouter चैट-पूरक सतह ने सही तरीके से नल किए गए क्षेत्रों के साथ एक वास्तविक पृष्ठ से सभी 25 टीम-सीजन पंक्तियाँ बाहर निकाली, जब प्रतिक्रिया को मार्कडाउन बाड़ के खिलाफ सुरक्षित किया गया। Claude जो प्रदान नहीं करता है वह पृष्ठ स्वयं है: एक सर्वर-साइड POST प्रत्येक पृष्ठ के लिए, रेंडरिंग और पहुँच के लिए बनाए गए फेच परत के माध्यम से, वह है जो रिकॉर्ड को निकासी के लिए मौजूद बनाता है।
क्या आप Claude को वास्तविक पृष्ठों के लिए तैयार हैं?
यहाँ फेच परत है Universal Scraping API — योजनाएँ और अनुरोध मात्रा प्राइसिंग पृष्ठ पर हैं, हर unlocker.webunlocker पैरामीटर के साथ डेवलपर डॉक्स में। मुफ्त योजना पर एक कुंजी बनाएं app.scrapeless.com और दोनों स्क्रिप्ट जैसी लिखी गई चलें।
अक्सर पूछे जाने वाले प्रश्न
Q: क्या Claude स्वयं वेबसाइटों को स्क्रैप कर सकता है?
नहीं। Claude API एक भाषा-मॉडल एंडपॉइंट है: यह आपके द्वारा प्रदान की गई पाठ से निकासी करता है और HTTP अनुरोध करने, JavaScript को रेंडर करने या सत्र पकड़ने में असमर्थ है। हर कार्यशील सेटअप इसे एक फेच परत के साथ जोड़ता है जो सच्चे पृष्ठ की सामग्री लौटाता है।
Q: मुझे वेब-स्क्रैपिंग निकासी के लिए कौन सा Claude मॉडल उपयोग करना चाहिए?
मूल API पर claude-haiku-4-5 (OpenRouter पर claude-haiku-4.5) — इस गाइड में लाइव रन ने इसका उपयोग किया और सभी 25 रिकॉर्ड सही तरीके से नल किए गए क्षेत्रों के साथ लौटाए। यह वर्तमान में सबसे सस्ती गैर-हेरीटेज Claude स्तर है; पुराना claude-3-haiku नाम एक पिछले पीढ़ी है जो अभी भी सूचीबद्ध है लेकिन वर्तमान अनुशंसा नहीं है।
Q: क्यों मेरा Claude JSON आउटपुट भले ही JSON मोड चालू हो, पार्स करने में विफल होता है?
OpenRouter एग्रीगेटर पथ पर, Claude अपनी आउटपुट को ```json मार्कडाउन बाड़ में लपेट सकता है भले ही response_format को json_object पर सेट किया गया हो। एक अग्रणी बाड़ को हटा दें json.loads को कॉल करने से पहले, या मूल API के output_config.format का उपयोग करें, जो उस विफलता मोड के बिना स्कीमा-विशिष्ट JSON को लागू करता है।
प्रश्न: क्लॉड ऐसे क्षेत्र का कैसे प्रबंधन करता है जो कभी-कभार स्रोत पृष्ठ से गायब होता है?
सही तरीके से, जब स्कीमा और प्रॉम्प्ट ऐसा कहते हैं। इस गाइड के स्कीमा ने ot_losses को ["integer", "null"] के रूप में चिह्नित किया और सिस्टम प्रॉम्प्ट ने शून्य स्थिति को स्पष्ट किया; लाइव चलाने ने उस सीजन के लिए null लौटाया जो सांख्यिकी से पूर्व था, बजाय इसके कि कोई मान उत्पन्न किया जाए।
प्रश्न: क्या क्लॉड के साथ स्क्रैपिंग कानूनी है?
एक्सट्रैक्शन परत संग्रह नियमों को नहीं बदलती। केवल सार्वजनिक पृष्ठों को प्राप्त करें, साइट की शर्तों और रोबोट्स निष exclusion प्रोटोकॉल द्वारा मानकीकृत रोबोट निर्देशों का सम्मान करें, मात्रा को सीमित रखें, और किसी भी व्यक्तिगत डेटा को लागू कानून के अंतर्गत संभालें - साथ ही मॉडल पक्ष पर एन्थ्रोपिक की उपयोग नीतियों का पालन करें।
स्क्रैपलेस में, हम केवल सार्वजनिक रूप से उपलब्ध डेटा का उपयोग करते हैं, जबकि लागू कानूनों, विनियमों और वेबसाइट गोपनीयता नीतियों का सख्ती से अनुपालन करते हैं। इस ब्लॉग में सामग्री केवल प्रदर्शन उद्देश्यों के लिए है और इसमें कोई अवैध या उल्लंघन करने वाली गतिविधियों को शामिल नहीं किया गया है। हम इस ब्लॉग या तृतीय-पक्ष लिंक से जानकारी के उपयोग के लिए सभी देयता को कोई गारंटी नहीं देते हैं और सभी देयता का खुलासा करते हैं। किसी भी स्क्रैपिंग गतिविधियों में संलग्न होने से पहले, अपने कानूनी सलाहकार से परामर्श करें और लक्ष्य वेबसाइट की सेवा की शर्तों की समीक्षा करें या आवश्यक अनुमतियाँ प्राप्त करें।



