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

pyquery वेब स्क्रैपिंग: पायथन में jQuery-स्टाइल HTML पार्सिंग

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

23-Jul-2026

TL;DR:

  • pyquery आपको Python में jQuery का API देता है। अगर आप $("div.quote").find("small.author").text() जानते हैं, तो आप पहले से ही pyquery जानते हैं।
  • जो pyquery नहीं करता है वो है फेच। यह चयन और पार्सिंग के लिए lxml को लपेटता है; इसमें कोई HTTP क्लाइंट नहीं है और यह कोई JavaScript नहीं चलाता।
  • फुटकर एक स्क्रिप्ट में दिखता है। एक JavaScript-निर्मित डेमो पेज पर एक साधारण GET pyquery को 0 क्वोट नोड्स देता है; वही URL Scrapeless यूनिवर्सल स्क्रैपिंग API के माध्यम से js_render के साथ सभी 10 देता है।
  • इस गाइड में निष्कर्ष वास्तविक है। एक लाइव रन ने सभी 10 क्वोट्स कलेक्टर, लेखकों और टैग्स के साथ रेंडर किए गए HTML से खींचने के लिए .items(), .find(), और .text() का उपयोग किया।
  • दो स्तर अलग रहते हैं। Scrapeless फेच और रेंडर करता है; pyquery चयन करता है। कोई भी दूसरे के काम में नहीं पहुंचता।
  • फेच साइड पर शुरू करने के लिए स्वतंत्र। अपने Scrapeless API कुंजी का निर्माण करें app.scrapeless.com पर।

pyquery क्या है, और क्या नहीं है

pyquery एक Python पुस्तकालय है जो lxml के ऊपर jQuery-शैली का API रखता है। आप मार्कअप को एक PyQuery ऑब्जेक्ट में लपेटते हैं — सामान्यतः d नामित — और फिर उसी कॉल्स के साथ चयन और यात्रा करते हैं जो एक फ्रंट-एंड डेवलपर पहले से ही करता है: d("selector"), .find(), .eq(), .text(), .attr(), .items()। ब्राउज़र से आने वाले किसी के लिए, यह "मैं DOM को क्वेरी करना जानता हूं" से "मैं इसे Python में निकाल सकता हूं" तक का सबसे छोटा रास्ता है, और क्योंकि यह lxml पर आधारित है, चयन के तहत तेज है।

यह एक पार्सिंग और चयन का पुस्तकालय है, और कुछ नहीं। pyquery में कोई HTTP क्लाइंट नहीं है, कोई सत्र नहीं रखता, और कोई JavaScript नहीं चलाता। इसे एक स्ट्रिंग दें और यह एक खोजने योग्य दस्तावेज बनाता है; इसे एक URL फेच करने के लिए कहें और, जबकि यह तकनीकी रूप से एक खींच सकता है, यह बिना रेंडरिंग के एक साधारण अनुरोध का उपयोग करता है, जो किसी भी पृष्ठ के लिए गलत उपकरण है जो स्क्रिप्ट द्वारा निर्मित है। इसलिए, हर "pyquery वेब स्क्रैपिंग" सेटअप में दो स्तर होते हैं: कुछ जो सत्यापन रेंडर किए गए HTML को लौटा देता है, और pyquery जो इससे चयन करता है। यह गाइड पहले स्तर के लिए Scrapeless यूनिवर्सल स्क्रैपिंग API का उपयोग करती है। व्यापक Python वेब स्क्रैपिंग ट्यूटोरियल आसपास के पारिस्थितिकी तंत्र को कवर करता है।

इंस्टॉल करें

pyquery और requests पूरी टूलचेन हैं। इस गाइड के लिए लिखी गई संस्करण pyquery 2.0.1 है:

bash Copy
pip install "pyquery==2.0.1" requests

अपनी कुंजी को पर्यावरण में रखें, कभी भी स्रोत में नहीं:

bash Copy
export SCRAPELESS_API_KEY="sk_your_scrapeless_key"

HTML प्राप्त करें जो पार्स करने लायक हो

चयन की गुणवत्ता फेच की वफादारी पर निर्भर करती है, इसलिए वहीं से शुरू करें। एक JavaScript-निर्मित पृष्ठ पर, एक साधारण HTTP क्लाइंट को जो मार्कअप प्राप्त होता है वह वही मार्कअप नहीं है जो एक पाठक देखता है — सामग्री केवल तब आती है जब स्क्रिप्ट DOM बनाती हैं, एक जीवन चक्र जिसे HTML स्क्रिप्टिंग विनिर्देश द्वारा परिभाषित किया गया है। एक स्क्रिप्ट pyquery स्वयं के माध्यम से अंतर की गणना करती है:

python Copy
# fidelity.py — जो pyquery देखता है: साधारण GET बनाम सर्वर-साइड रेंडरिंग
import os

import requests
from pyquery import PyQuery as pq

URL = "https://quotes.toscrape.com/js/"

plain = requests.get(URL, timeout=60).text
print("plain GET chars:", len(plain), "| quote nodes:", pq(plain, parser="html")("div.quote").length)

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": URL, "js_render": True}},
    timeout=120,
)
resp.raise_for_status()
rendered = resp.json().get("data", "")
print("rendered chars:", len(rendered), "| quote nodes:", pq(rendered, parser="html")("div.quote").length)

यह रन साधारण फेच के लिए 0 क्वोट नोड्स और रेंडर किए गए के लिए 10 क्वोट नोड्स प्रिंट करता है:

text Copy
plain GET chars: 5806 | quote nodes: 0
rendered chars: 8940 | quote nodes: 10

रेंडरिंग, अनलॉकिंग, और प्रॉक्सी राउटिंग सभी उस एक पोस्ट में सर्वर-साइड होती हैं — यूनिवर्सल स्क्रैपिंग API फेच लेयर है, और रेंडर किया गया मार्कअप वही है जिससे pyquery चयन करता है।

jQuery API के साथ निष्कर्ष निकालें

सच्चा HTML हाथ में लेने पर, pyquery निष्कर्ष निकालने का काम जQuery की तरह करता है। .items() चयन को PyQuery ऑब्जेक्ट्स के एक इटरेटर में बदलता है, .find() प्रत्येक के लिए एक सब-सेलेक्टर को सीमित करता है, और .text() पाठ को पढ़ता है — सेलेक्टर्स W3C सेलेक्सन विनिर्देश का पालन करते हैं, वही सिंटैक्स जो jQuery उपयोग करता है:

python Copy
# extract.py — रेंडर किया गया पृष्ठ फेच करें, फिर jQuery API के साथ चयन करें
import os

import requests
from pyquery import PyQuery as pq

resp = requests.post(
    "https://api.scrapeless.com/api/v2/unlocker/request",

headers={"सामग्री-प्रकार": "अनुप्रयोग/जेसन", "x-api-token": os.environ["SCRAPELESS_API_KEY"]},
json={"एक्टर": "unlocker.webunlocker", "इनपुट": {"url": "https://quotes.toscrape.com/js/", "js_render": True}},
timeout=120,
)
resp.raise_for_status()
d = pq(resp.json().get("data", ""), parser="html")

रिकॉर्ड = []
for quote in d("div.quote").items():
रिकॉर्ड.append({
"पाठ": quote.find("span.text").text(),
"लेखक": quote.find("small.author").text(),
"टैग": [pq(tag).text() for tag in quote.find("a.tag").items()],
})
print("रिकॉर्ड:", len(रिकॉर्ड))
print("पहला लेखक:", रिकॉर्ड[0]["लेखक"])
print("पहले टैग:", रिकॉर्ड[0]["टैग"])

Copy
प्रत्यक्ष रन ने सभी 10 रिकॉर्ड, टैग और सभी का चयन किया:

```text
रिकॉर्ड: 10
पहला लेखक: अल्बर्ट आइंस्टीन
पहले टैग: ['परिवर्तन', 'गहरा-चिंतन', 'चिंतन', 'दुनिया']

यही पूरा स्क्रैपर है: एक POST डेटा लाने और रेंडर करने के लिए, एक PyQuery ऑब्जेक्ट क्वेरी करने के लिए। .items() पुनरावृत्तिकर्ता pyquery अभिव्यक्ति है जिसे याद रखना चाहिए - यह चयन को प्रति-रिकॉर्ड ऑब्जेक्ट्स में बदलता है जिसमें आप .find() कर सकते हैं, जो jQuery के .each() का सीधा समानांतर है।

अपनी API कुंजी मुफ्त योजना पर प्राप्त करें: app.scrapeless.com

उन्नत पैटर्न

  • हमेशा .items() के साथ पुनरावृत्त करें। PyQuery चयन पर सीधे लूप करने से कच्चे lxml तत्व मिलते हैं, न कि PyQuery ऑब्जेक्ट्स, इसलिए .find() टूट जाता है। .items() आपको हर एक पर पूर्ण API के साथ लिपटे ऑब्जेक्ट्स देता है।
  • .attr() के साथ विशेषताएँ पढ़ें। quote.find("a::attr(href)") pyquery का वाक्यविन्यास नहीं है; इसका इस्तेमाल करें quote.find("a").attr("href"), ठीक जQuery की तरह।
  • वास्तविक पृष्ठों के लिए parser="html" पास करें। यह lxml के सहिष्णु HTML पार्सर का चयन करता है, जो असंबंधित मार्कअप को संभालता है जो वास्तविक साइटें भेजती हैं; डिफ़ॉल्ट आपकी अपेक्षा से अधिक सख्त हो सकता है।
  • चेन करें, पुनः-प्रश्न न करें। d("div.quote").eq(0).find("small.author") प्रत्येक चरण को अंतिम तक सीमित करता है, जो तेज़ और पहले से ज्ञात jQuery पढ़ने के तरीकों के निकट है।

समस्या निवारण

  • ऐसे पृष्ठ से शून्य नोड जो आप ब्राउज़र में देख सकते हैं। सामग्री JavaScript द्वारा उत्पन्न की गई है और आपकी फेच पहले से रेंडर किए गए HTML को लौटा रही है। पहले स्क्रिप्ट की तरह ज्ञात चयन गिनें; एक निकट-खाली दस्तावेज़ एक फेच समस्या है, जिसे js_render के साथ ठीक किया गया है, न कि चयन समस्या।
  • .find() AttributeError उत्पन्न करता है। आपने चयन को सीधे पुनरावृत्त किया बजाय कि .items() के साथ, इसलिए आपको एक कच्चा lxml तत्व मिला। लूप को for x in sel.items(): में स्विच करें।
  • .text() सब कुछ अनुक्रमित करके लौटाता है। pyquery वंशज के पाठ को जोड़ता है। एक अधिक विशिष्ट चयनकर्ता के साथ तंग दायरा बनाएं, या एकल नोड को .eq(0).text() के साथ पढ़ें।
  • संकेतन गलत लगता है। प्रतिक्रिया पाठ को pyquery-प्रथम पास करें parser="html" के साथ; lxml दस्तावेज़ की घोषित संकेतन को पढ़ता है जब पार्सर HTML हो।

निष्कर्ष

pyquery उस चयन परत के रूप में अपना स्थान अर्जित करता है जो jQuery से बात करता है: वही .find(), .text(), और .items() कॉल जो आप ब्राउज़र में जानते हैं, एक तेज़ lxml पेड़ के ऊपर। वह परत जो तय करती है कि क्या इनमें से कोई भी संभव है वह फेच है - पहले स्क्रिप्ट का 0 बनाम 10 की गिनती इसे तय करती है - और एक सर्वर-रेंडर्ड POST गैप को बंद करता है। दोनों को साथ में जोड़ें और डेमो पृष्ठ के दस उद्धरण साफ रिकॉर्ड के रूप में आते हैं, जिस तरह से आप पहले से सोचते हैं।

एक मुफ्त Scrapeless खाता बनाएं ताकि आप एक API कुंजी प्राप्त कर सकें, और डेवलपर दस्तावेज़ unlocker.webunlocker पैरामीटर को कवर करते हैं। जब आप एक नियमित काम की योजना बनाते हैं तो Scrapeless मूल्य निर्धारण देखें।

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

प्रश्न: क्या pyquery अपने आप वेबसाइटों को स्क्रैप कर सकता है?

वास्तव में नहीं। pyquery एक URL खींच सकता है, लेकिन यह केवल एक साधारण अनुरोध के साथ ऐसा करता है और कोई JavaScript रेंडरिंग नहीं करता है, इसलिए आधुनिक पृष्ठ पर यह खाली मार्कअप से चयन करता है। इसे एक पार्सर के रूप में मानें: इसे एक फेच परत के साथ जोड़ें - यहाँ Scrapeless यूनिवर्सल स्क्रैपिंग API, जो पृष्ठ को सर्वर-साइड रेंडर करता है - और pyquery लौटाए गए HTML से चयन करने का काम संभालता है।

प्रश्न: क्या pyquery jQuery के समान है?

यह Python में jQuery के API को दर्शाता है - d("selector"), .find(), .text(), .attr(), .items() - लेकिन यह lxml पर सर्वर-साइड चलाता है, न कि एक ब्राउज़र में, इसलिए यह स्थिर मार्कअप से चयन करता है और स्क्रिप्ट निष्पादित नहीं करता या घटनाओं को संभालता है। चयन वाक्यविन्यास स्थानांतरित होता है; रनटाइम नहीं।

प्रश्न: pyquery या BeautifulSoup?

पसंद। pyquery jQuery की तरह पढ़ता है और यदि आप फ्रंट-एंड काम से आ रहे हैं तो यह एक स्वाभाविक फिट है; BeautifulSoup का एक अधिक Pythonic API है। दोनों एक ही HTML को पार्स करते हैं, और दोनों को JavaScript-जनित पृष्ठों के लिए एक अलग फेच परत की आवश्यकता होती है।

प्रश्न: क्या pyquery JavaScript-जेनरेटेड पृष्ठों को संभालता है?
अपने आप में नहीं - यह कभी स्क्रिप्ट निष्पादित नहीं करता है। यदि सामग्री प्रारंभिक HTML के बाद लोड होती है, तो एक साधारण फेच pyquery को एक खाली दस्तावेज़ सौंपता है। पहले Scrapeless API के माध्यम से js_render के साथ पृष्ठ लोड करें, फिर इस मार्गदर्शिका के अनुसार प्रस्तुत HTML से चयन करें।

प्रश्न: क्या pyquery के साथ स्क्रैपिंग कानूनी है?

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

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

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

सूची