
wxpath - XPath के साथ घोषणात्मक वेब क्रॉलिंग; एक वेब क्वेरी भाषा (WQL)
नया: TUI - wxpath एक्सप्रेशन्स का परीक्षण करने और डेटा निर्यात करने के लिए इंटरैक्टिव टर्मिनल इंटरफ़ेस (Textual द्वारा संचालित)।

Python 3.10+ आवश्यक है।
pip install wxpath
# TUI समर्थन के लिए:
pip install "wxpath[tui]"
# uv के माध्यम से तुरंत TUI लॉन्च करें:
uvx --from "wxpath[tui]" wxpath-tui
wxpath एक घोषणात्मक वेब क्रॉलर है जिसमें ट्रैवर्सल सीधे XPath में व्यक्त किया जाता है। इम्पेरेटिव क्रॉल लूप लिखने के बजाय, wxpath आपको एक ही एक्सप्रेशन में यह वर्णन करने देता है कि क्या अनुसरण करना है और क्या निकालना है। wxpath उस एक्सप्रेशन को समवर्ती रूप से, breadth-first-ish, निष्पादित करता है और परिणामों को खोजे जाने पर स्ट्रीम करता है।
यह एक्सप्रेशन एक पेज लाता है, लिंक निकालता है, और उन्हें समवर्ती रूप से स्ट्रीम करता है - किसी क्रॉल लूप की आवश्यकता नहीं:
import wxpath
expr = "url('https://quotes.toscrape.com')//a/@href"
for link in wxpath.wxpath_async_blocking_iter(expr):
print(link)
url(...) ऑपरेटर और /// सिंटैक्स प्रस्तुत करके, wxpath का इंजन रिकर्सिव (या पैजिनेटेड) वेब क्रॉलिंग और एक्सट्रैक्शन करने में सक्षम है:
import wxpath
path_expr = """
url('https://quotes.toscrape.com')
///url(//a/@href)
//a/@href
"""
for item in wxpath.wxpath_async_blocking_iter(path_expr, max_depth=1):
print(item)
अधिकांश वेब स्क्रेपर्स आपको पहले क्रॉल कंट्रोल फ्लो और दूसरे एक्सट्रैक्शन लिखने के लिए बाध्य करते हैं।
wxpath इन दो चरणों को एक में समेटता है:
ग्राफ से सीधे स्वच्छ, संरचित JSON पदानुक्रम निकालें - अपने LLMs को सिग्नल दें, शोर नहीं। अधिक विवरण के लिए LangChain इंटीग्रेशन देखें।
wxpath डिटर्मिनिस्टिक है (अर्थात: LLMs द्वारा संचालित नहीं)। हालांकि हम गारंटी नहीं दे सकते कि नेटवर्क स्थिर है, हम गारंटी दे सकते हैं कि ट्रैवर्सल स्थिर है।
दस्तावेज़ीकरण अब यहाँ उपलब्ध है।
url(...) और ///url(...) समझाया गयाimport wxpath
from wxpath.settings import CRAWLER_SETTINGS
# विनम्रता के लिए कस्टम हेडर; कुछ साइटों के लिए आवश्यक (जैसे, Wikipedia)
CRAWLER_SETTINGS.headers = {'User-Agent': 'my-app/0.4.0 (contact: [email protected])'}
# क्रॉल करें, फ़ील्ड निकालें, एक नॉलेज ग्राफ बनाएँ
path_expr = """
url('https://en.wikipedia.org/wiki/Expression_language')
///url(
//main//a/@href[
starts-with(., '/wiki/') and not(contains(., ':'))
]
)
/map{
'title': (//span[contains(@class, "mw-page-title-main")]/text())[1] ! string(.),
'url': string(base-uri(.)),
'short_description': //div[contains(@class, 'shortdescription')]/text() ! string(.),
'forward_links': //div[@id="mw-content-text"]//a/@href ! string(.)
}
"""
for item in wxpath.wxpath_async_blocking_iter(path_expr, max_depth=1):
print(item)
नोट: कुछ साइटें (Wikipedia सहित) उचित हेडर के बिना अनुरोधों को ब्लॉक कर सकती हैं।
कस्टम User-Agent सेट करने के लिए उन्नत: इंजन और क्रॉलर कॉन्फ़िगरेशन देखें।
उपरोक्त एक्सप्रेशन निम्नलिखित कार्य करता है:
https://en.wikipedia.org/wiki/Expression_language पर शुरू होता है।<main> सेक्शन में उन लिंक्स को फ़िल्टर करता है जो /wiki/ से शुरू होते हैं और उनमें कोलन (:) नहीं होता।url(...) और ///url(...) समझाया गयाurl(...) एक कस्टम ऑपरेटर है जो उपयोगकर्ता-निर्दिष्ट या आंतरिक रूप से उत्पन्न URL की सामग्री लाता है और आगे की XPath प्रोसेसिंग के लिए इसे lxml.html.HtmlElement के रूप में लौटाता है।///url(...) एक डीप क्रॉल को इंगित करता है। यह रनटाइम इंजन को निर्दिष्ट max_depth तक लिंक्स का अनुसरण जारी रखने के लिए कहता है। बार-बार url() हॉप्स के विपरीत, यह एक ही एक्सप्रेशन को गहरे ग्राफ अन्वेषण का वर्णन करने की अनुमति देता है। चेतावनी: ट्रैवर्सल विस्फोट से बचने के लिए सावधानी और बाधाओं (max_depth या XPath प्रेडिकेट्स के माध्यम से) के साथ उपयोग करें।भाषा डिज़ाइन के विवरण के लिए DESIGN.md देखें। आप मूल अवधारणाओं को देखेंगे और भाषा को शुरू से डिज़ाइन करेंगे।
wxpath एक एक्सप्रेशन को ट्रैवर्सल और एक्सट्रैक्शन चरणों की सूची के रूप में मूल्यांकित करता है (आंतरिक रूप से Segments कहा जाता है)।
url(...) क्रॉल कार्यों को स्थिर रूप से (एक निश्चित URL के माध्यम से) या गतिशील रूप से (XPath एक्सप्रेशन से व्युत्पन्न URL के माध्यम से) बनाता है। URLs को वैश्विक रूप से, best-effort आधार पर डिडुप्लिकेट किया जाता है - प्रति-गहराई नहीं।
XPath सेगमेंट लाए गए दस्तावेज़ों पर कार्य करते हैं (तुरंत पूर्ववर्ती url(...) ऑपरेशनों के माध्यम से लाए गए)।
///url(...) डीप क्रॉलिंग को इंगित करता है - यह max_depth तक breadth-first-ish आगे बढ़ता है।
परिणाम तैयार होते ही प्राप्त होते हैं।
wxpath asyncio/aiohttp-first है, जो क्रॉलिंग और डेटा निष्कर्षण के लिए एक एसिंक्रोनस API प्रदान करता है।
import asyncio
from wxpath import wxpath_async
items = []
async def main():
path_expr = "url('https://en.wikipedia.org/wiki/Expression_language')///url(//@href[starts-with(., '/wiki/')])//a/@href"
async for item in wxpath_async(path_expr, max_depth=1):
items.append(item)
asyncio.run(main())
wxpath एक asyncio-in-sync API भी प्रदान करता है, जो सिंक्रोनस कोड की सरलता बनाए रखते हुए कई पेजों को समवर्ती रूप से क्रॉल करने की अनुमति देता है। यह विशेष रूप से सख्ती से सिंक्रोनस निष्पादन वातावरण (यानी, asyncio इवेंट लूप के अंदर नहीं) में क्रॉल के लिए उपयोगी है जहाँ प्रदर्शन चिंता का विषय है।
from wxpath import wxpath_async_blocking_iter
path_expr = "url('https://en.wikipedia.org/wiki/Expression_language')///url(//@href[starts-with(., '/wiki/')])//a/@href"
items = list(wxpath_async_blocking_iter(path_expr, max_depth=1))
wxpath डिफ़ॉल्ट रूप से WXPathEngine(..., robotstxt=True) कंस्ट्रक्टर के माध्यम से robots.txt का सम्मान करता है।
wxpath Python API संरचित ऑब्जेक्ट प्रदान करता है।
एक्सप्रेशन के आधार पर, परिणामों में शामिल हो सकते हैं:
lxml.* और lxml.html.* ऑब्जेक्टelementpath.datatypes.* ऑब्जेक्ट (XPath 3.1 सुविधाओं के लिए)WxStr (उत्पत्ति के साथ स्ट्रिंग मान)CLI इन ऑब्जेक्ट्स को प्रदर्शन के लिए सादे JSON में फ्लैट करता है। Python API डिफ़ॉल्ट रूप से संरचना को सुरक्षित रखता है।
wxpath XPath 3.1 समर्थन प्रदान करने के लिए elementpath लाइब्रेरी का उपयोग करता है, जो maps, arrays, और अधिक जैसी उन्नत XPath सुविधाओं को सक्षम करता है। यह आपको अधिक शक्तिशाली XPath क्वेरी लिखने की अनुमति देता है।
path_expr = """
url('https://en.wikipedia.org/wiki/Expression_language')
///url(//div[@id='mw-content-text']//a/@href)
/map{
'title':(//span[contains(@class, "mw-page-title-main")]/text())[1],
'short_description':(//div[contains(@class, "shortdescription")]/text())[1],
'url'://link[@rel='canonical']/@href[1]
}
"""
# [...
# {'title': 'Computer language',
# 'short_description': 'Formal language for communicating with a computer',
# 'url': 'https://en.wikipedia.org/wiki/Computer_language'},
# {'title': 'Machine-readable medium and data',
# 'short_description': 'Medium capable of storing data in a format readable by a machine',
# 'url': 'https://en.wikipedia.org/wiki/Machine-readable_medium_and_data'},
# {'title': 'Domain knowledge',
# 'short_description': 'Specialist knowledge within a specific field',
# 'url': 'https://en.wikipedia.org/wiki/Domain_knowledge'},
# ...]
wxpath क्रॉल प्रगति को ट्रैक करने के लिए एक प्रोग्रेस बार (tqdm के माध्यम से) प्रदान करता है। यह लंबे समय तक चलने वाले क्रॉल के लिए विशेष रूप से उपयोगी है।
engine.run(..., progress=True) सेट करके, या किसी भी wxpath_async*(...) फ़ंक्शन में progress=True पास करके सक्षम करें।
items = wxpath.wxpath_async_blocking("...", progress=True)
> 100%|██████████████████████████████████████████████████████████▎| 469/471 [00:05<00:00, 72.00it/s, depth=2, yielded=457]
wxpath टर्मिनल से सीधे wxpath एक्सप्रेशन्स के साथ त्वरित प्रयोग और निष्पादन के लिए एक कमांड-लाइन इंटरफ़ेस (CLI) प्रदान करता है।
निम्नलिखित उदाहरण दर्शाता है कि "Expression language" पेज से शुरू करके Wikipedia को कैसे क्रॉल किया जाए, अन्य विकी पेजों के लिंक कैसे निकाले जाएँ, और प्रत्येक लिंक किए गए पेज से विशिष्ट फ़ील्ड कैसे प्राप्त करें।
नोट: वेब सामग्री की निरंतर बदलती प्रकृति के कारण, आउटपुट समय के साथ भिन्न हो सकता है।
> wxpath --depth 1 \
--header "User-Agent: my-app/0.1 (contact: [email protected])" \
"url('https://en.wikipedia.org/wiki/Expression_language') \
///url(//div[@id='mw-content-text']//a/@href[starts-with(., '/wiki/') \
and not(matches(@href, '^(?:/wiki/)?(?:Wikipedia|File|Template|Special|Template_talk|Help):'))]) \
/map{ \
'title':(//span[contains(@class, 'mw-page-title-main')]/text())[1], \
'short_description':(//div[contains(@class, 'shortdescription')]/text())[1], \
'url':string(base-uri(.)), \
'backlink':wx:backlink(.), \
'depth':wx:depth(.) \
}"
{"title": "Computer language", "short_description": "Formal language for communicating with a computer", "url": "https://en.wikipedia.org/wiki/Computer_language", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Machine-readable medium and data", "short_description": "Medium capable of storing data in a format readable by a machine", "url": "https://en.wikipedia.org/wiki/Machine_readable", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Domain knowledge", "short_description": "Specialist knowledge within a specific field", "url": "https://en.wikipedia.org/wiki/Domain_knowledge", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Advanced Boolean Expression Language", "short_description": "Hardware description language and software", "url": "https://en.wikipedia.org/wiki/Advanced_Boolean_Expression_Language", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Data Analysis Expressions", "short_description": "Formula and data query language", "url": "https://en.wikipedia.org/wiki/Data_Analysis_Expressions", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Jakarta Expression Language", "short_description": "Computer programming language", "url": "https://en.wikipedia.org/wiki/Jakarta_Expression_Language", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Rights Expression Language", "short_description": [], "url": "https://en.wikipedia.org/wiki/Rights_Expression_Language", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
{"title": "Computer science", "short_description": "Study of computation", "url": "https://en.wikipedia.org/wiki/Computer_science", "backlink": "https://en.wikipedia.org/wiki/Expression_language", "depth": 1.0}
कमांड लाइन विकल्प:
--depth <depth> Max crawl depth
--verbose [true|false] Provides superficial CLI information
--debug [true|false] Provides verbose runtime output and information
--concurrency <concurrency> Number of concurrent fetches
--concurrency-per-host <concurrency> Number of concurrent fetches per host
--header "Key:Value" Add a custom header (e.g., 'Key:Value'). Can be used multiple times.
--respect-robots [true|false] (Default: True) Respects robots.txt
--cache [true|false] (Default: False) Persist crawl results to a local database
wxpath इंटरैक्टिव एक्सप्रेशन परीक्षण और डेटा निष्कर्षण के लिए एक टर्मिनल इंटरफ़ेस (TUI) प्रदान करता है।
अधिक विवरण के लिए TUI क्विकस्टार्ट देखें।
wxpath वैकल्पिक रूप से क्रॉल परिणामों को एक स्थानीय डेटाबेस में संग्रहीत करता है। यह विशेष रूप से उपयोगी है जब आप बड़ी संख्या में URLs क्रॉल कर रहे हों, और आप क्रॉल को रोकने, एक्सट्रैक्शन एक्सप्रेशन बदलने, या अन्यथा क्रॉल को पुनः आरंभ करने का निर्णय लेते हैं।
wxpath दो बैकएंड का समर्थन करता है: sqlite और redis। SQLite एकल वर्कर (यानी, engine.crawler.concurrency == 1) के साथ छोटे पैमाने के क्रॉल के लिए बढ़िया है। Redis कई वर्करों के साथ बड़े पैमाने के क्रॉल के लिए बढ़िया है। sqlite बैकएंड का उपयोग करते समय आपको एक चेतावनी मिलेगी यदि min(engine.crawler.concurrency, engine.crawler.per_host) > 1।
उपयोग करने के लिए, आपको उपयुक्त वैकल्पिक निर्भरता स्थापित करनी होगी:
pip install wxpath[cache-sqlite]
pip install wxpath[cache-redis]
निर्भरता स्थापित होने के बाद, आपको कैश सक्षम करना होगा:
from wxpath.settings import SETTINGS
# कैशिंग सक्षम करने के लिए; sqlite डिफ़ॉल्ट है
SETTINGS.http.client.cache.enabled = True
# redis बैकएंड के लिए
SETTINGS.http.client.cache.enabled = True
SETTINGS.http.client.cache.backend = "redis"
SETTINGS.http.client.cache.redis.address = "redis://localhost:6379/0"
# wxpath को सामान्य रूप से चलाएँ
items = list(wxpath_async_blocking_iter('...', max_depth=1, engine=engine))
सेटिंग्स के विवरण के लिए settings.py देखें।
wxpath एक प्लग करने योग्य हुक सिस्टम का समर्थन करता है जो आपको क्रॉलिंग और एक्सट्रैक्शन व्यवहार को संशोधित करने की अनुमति देता है। आप URLs को प्रीप्रोसेस करने, HTML को पोस्ट-प्रोसेस करने, निकाले गए मानों को फ़िल्टर करने आदि के लिए हुक पंजीकृत कर सकते हैं। हुक उसी क्रम में निष्पादित किए जाएंगे जिस क्रम में वे पंजीकृत हैं। हुक प्रदर्शन को प्रभावित कर सकते हैं।
from wxpath import hooks
@hooks.register
class OnlyEnglish:
def post_parse(self, ctx, elem):
lang = elem.xpath('string(/html/@lang)').lower()[:2]
return elem if lang in ("en", "") else None
नोट: हुक सिंक्रोनस या एसिंक्रोनस हो सकते हैं, लेकिन एक प्रोजेक्ट में सभी हुकों को एक ही शैली का पालन करना चाहिए। सिंक और async हुक्स को मिलाना समर्थित नहीं है और इससे अप्रत्याशित व्यवहार हो सकता है।
from wxpath import hooks
@hooks.register
class OnlyEnglish:
async def post_parse(self, ctx, elem):
lang = elem.xpath('string(/html/@lang)').lower()[:2]
return elem if lang in ("en", "") else None
JSONLWriter (उपनाम NDJSONWriter) एक अंतर्निहित हुक है जो निकाले गए डेटा को न्यूलाइन-डिलीमिटेड JSON फ़ाइल में लिखता है। यह परिणामों को एक संरचित प्रारूप में संग्रहीत करने के लिए उपयोगी है जिसे बाद में आसानी से संसाधित किया जा सकता है।
from wxpath import hooks
hooks.register(hooks.JSONLWriter)
Python 3.10+ आवश्यक है।
pip install wxpath
पर्सिस्टेंस/कैशिंग के लिए, wxpath निम्नलिखित बैकएंड का समर्थन करता है:
pip install wxpath[cache-sqlite]
pip install wxpath[cache-redis]
अधिक उपयोग उदाहरणों के लिए EXAMPLES.md देखें।
अन्य वेब-स्क्रैपिंग टूल के साथ तुलना के लिए COMPARISONS.md देखें।
आप इंजन और क्रॉलर के व्यवहार को इस प्रकार बदल सकते हैं:
from wxpath import wxpath_async_blocking_iter
from wxpath.core.runtime import WXPathEngine
from wxpath.http.client.crawler import Crawler
crawler = Crawler(
concurrency=8,
per_host=2,
timeout=10,
respect_robots=False,
headers={
"User-Agent": "my-app/0.1.0 (contact: [email protected])", # Wikipedia जैसी साइटें इसकी सराहना करेंगी
},
)
# यदि `crawler` निर्दिष्ट नहीं है, तो दिए गए concurrency, per_host, और respect_robots मानों के साथ,
# या डिफ़ॉल्ट के साथ एक डिफ़ॉल्ट Crawler बनाया जाएगा।
engine = WXPathEngine(
# concurrency: int = 16,
# per_host: int = 8,
# respect_robots: bool = True,
# allowed_response_codes: set[int] = {200},
# allow_redirects: bool = True,
crawler=crawler,
)
path_expr = "url('https://en.wikipedia.org/wiki/Expression_language')//url(//main//a/@href)"
items = list(wxpath_async_blocking_iter(path_expr, max_depth=1, engine=engine))
wxpath_async*) विकल्पmax_depth: int = 1progress: bool = Falseengine: WXPathEngine | None = Noneyield_errors: bool = Falseआप कैशिंग, थ्रॉटलिंग, समवर्तीता और अधिक सक्षम करने के लिए settings.py का भी उपयोग कर सकते हैं।
max_depth तक पहुँचने पर समाप्त होने के लिए होते हैं।निम्नलिखित सुविधाएँ अभी तक समर्थित नहीं हैं:
यह प्रोजेक्ट प्रारंभिक विकास में है। मूल अवधारणाएँ स्थिर हैं, लेकिन API और सुविधाएँ बदल सकती हैं। कृपया समस्याओं की रिपोर्ट करें - विशेष रूप से डेडलॉक किए गए क्रॉल या अप्रत्याशित व्यवहार - और कोई भी सुविधा जिसे आप देखना चाहते हैं (कोई गारंटी नहीं कि वे लागू की जाएँगी)।
///) के लिए असीमित विस्तार (ट्रैवर्सल विस्फोट) से बचने के लिए उपयोगकर्ता अनुशासन की आवश्यकता होती है।max_depth, और XPath प्रेडिकेट्स और फ़िल्टर का उपयोग करने पर विचार करें।यदि आप wxpath के साथ क्रॉलर/डेटा फ़ीड बनाने या संचालित करने (एक्सट्रैक्शन, शेड्यूलिंग, मॉनिटरिंग, ब्रेकेज फिक्स) या अन्य वेब-स्क्रैपिंग आवश्यकताओं में सहायता चाहते हैं, तो कृपया मुझसे संपर्क करें: [email protected]।
यदि आप wxpath पसंद करते हैं और इसके विकास का समर्थन करना चाहते हैं, तो कृपया दान करने पर विचार करें।
wxpath semver का पालन करता है: <MAJOR>.<MINOR>.<PATCH>।
हालाँकि, pre-1.0.0 0.<MAJOR>.<MINOR|PATCH> का पालन करता है।
AGPL-3.0