C++ वेब स्क्रैपिंग: प्रदर्शन-आधारित परियोजनाओं के लिए एक व्यावहारिक मार्गदर्शिका
Expert Network Defense Engineer
TL;DR:
- C++ एक शानदार स्क्रैपिंग पार्सर है और एक अजीब स्क्रैपिंग क्लाइंट। libxml2 एचटीएमएल को मूल गति पर पार्स करता है, लेकिन C++ में TLS फिंगरप्रिंटिंग, प्रॉक्सी रोटेशन, और जावास्क्रिप्ट रेंडरिंग करना अपने आप में एक परियोजना है।
- काम को विभाजित करें: रेंडरिंग एपीआई को फेच करने दें, C++ को पार्स करने दें। libcurl लक्षित UURL को स्क्रैपलेस यूनिवर्सल स्क्रैपिंग एपीआई पर POST करता है, जो रेंडर्ड एचटीएमएल लौटाता है; libxml2 + XPath स्थानीय रूप से तेज़ निष्कर्षण करता है।
js_render: trueएक खाली पृष्ठ को डेटा में बदलता है। कई साइटें अपने सामग्री को जावास्क्रिप्ट के साथ बनाती हैं; एपीआई इसे सर्वर-साइड चलाता है ताकि आपका C++ कोड पूरा DOM प्राप्त करे, न कि एक खाली खोल।- सारा क्लाइंट दो लाइब्रेरीज हैं जो आप पहले से जानते हैं। libcurl HTTP POST के लिए, libxml2 एचटीएमएल + XPath के लिए — कोई हेडलेस ब्राउज़र एम्बेड करने की आवश्यकता नहीं, C++ में कोई एंटी-बॉट स्टैक बनाए रखने की आवश्यकता नहीं।
- यह सत्यापित रूप से छोटा है। नीचे दिया गया पूरा कार्यक्रम एक
g++लाइन के साथ संकलित होता है और लाइव चलाया गया: HTTP 200, 51 KB रेंडर्ड एचटीएमएल, 20 उत्पाद शीर्षक पार्स हुए। - शुरू करने के लिए नि:शुल्क। नए स्क्रैपलेस खातों में मुफ्त रनटाइम शामिल है — app.scrapeless.com पर साइन अप करें।
परिचय: C++ स्क्रैपिंग में कहां फिट होता है
C++ स्क्रैपिंग में एक कारण के लिए आता है: गति। जब आप लाखों पृष्ठों का पार्स कर रहे होते हैं, libxml2 मूल गति पर एचटीएमएल को पार्स करना एक इंटरप्रेटेड पार्सर पर हावी होता है। समस्या यह है कि पार्स से पहले सब कुछ है। आधुनिक लक्ष्यों ने एक्सेस को TLS फिंगरप्रिंटिंग और एंटी-बॉट डिफेंस, IP प्रतिष्ठा, और जावास्क्रिप्ट के पीछे रखा है जो वास्तव में काम करना चाहिए इससे पहले कि सामग्री अस्तित्व में आए। इसे C++ में पुनः उत्पन्न करना — एक स्टील्थ HTTP स्टैक, एक प्रॉक्सी पूल, एक एम्बेडेड ब्राउज़र इंजन — स्क्रैपिंग से कहीं अधिक काम है।
व्यवहारिक विभाजन यह है कि C++ को उसके खराब हिस्से को करने से रोकें। फेच को संभालने के लिए एक रेंडरिंग एपीआई का उपयोग करें — TLS, प्रॉक्सी, जावास्क्रिप्ट, एंटी-बॉट — और C++ को पार्स करने के लिए पूरा एचटीएमएल सौंपें। आपका प्रोग्राम दो अच्छी तरह से समझे जाने वाले टुकड़ों में विभाजित हो जाता है: libcurl एक HTTPS POST करता है, और libxml2 परिणाम पर XPath चलाता है।
यह गाइड स्क्रैपलेस यूनिवर्सल स्क्रैपिंग एपीआई के साथ ठीक वही बनाता है। अंत में पूरा कार्यक्रम संकलित और लाइव चलाया गया; इसमें दिए गए नंबर वास्तविक कैप्चर हैं।
आप इसके साथ क्या कर सकते हैं
- मूल गति पर पार्स करें — libxml2 + XPath रेंडर्ड एचटीएमएल पर, कोई इंटरप्रेटर ओवरहेड नहीं।
- जावास्क्रिप्ट-भारी साइटों को स्क्रैप करें बिना अपने C++ बाइनरी में ब्राउज़र एम्बेड किए।
- एंटी-बॉट स्टैक को छोड़ें — TLS फिंगरप्रिंटिंग, प्रॉक्सी रोटेशन, और CAPTCHA हैंडलिंग एपीआई में होती है, आपके कोड में नहीं।
- स्क्रैपिंग को मौजूदा C++ सिस्टम में डालें — एक ट्रेडिंग पाइपलाइन, एक डेटा टूल, एक नेटिव सेवा — केवल libcurl और libxml2 के साथ।
- अवकाश की स्केलिंग करें — रेंडरिंग सर्वर-साइड पर होती है, इसलिए आपका बाइनरी हल्का रहता है।
क्यों स्क्रैपलेस यूनिवर्सल स्क्रैपिंग एपीआई
स्क्रैपलेस यूनिवर्सल स्क्रैपिंग एपीआई एक लक्षित यूआरएल लेता है और रेंडर्ड, अनब्लॉक एचटीएमएल लौटाता है। विशेष रूप से C++ क्लाइंट के लिए, यह लाता है:
- सर्वर-साइड जावास्क्रिप्ट रेंडरिंग —
js_render: trueपूरा DOM लौटाता है, इसलिए libxml2 वास्तविक सामग्री देखता है। - 195+ देशों में आवासीय प्रॉक्सी — फेच ट्रस्टेड IP से होते हैं; आप कभी भी एक पूल का प्रबंधन नहीं करते हैं।
- एंटी-बॉट हैंडलिंग — TLS फिंगरप्रिंटिंग और चुनौती हल करना एपीआई-साइड होता है, आपके बाइनरी से बाहर।
- एक साधारण HTTPS POST — लिंक करने के लिए कोई SDK नहीं; libcurl आपके लिए आवश्यक सभी C++ है।
- एक सरल लिफाफा —
{"code":200,"data":"<html>…"}, बिना भारी JSON निर्भरता के संभालना आसान।
app.scrapeless.com पर मुफ्त योजना पर अपना एपीआई की प्राप्त करें।
आवश्यकताएँ
- एक C++17 कंपाइलर (g++ या clang)
- libcurl और libxml2 विकास हेडर
- एक स्क्रैपलेस खाता और एपीआई की — app.scrapeless.com पर साइन अप करें
डेबियन/उबंटू पर:
bash
sudo apt-get install -y libcurl4-openssl-dev libxml2-dev
bash
export SCRAPELESS_API_KEY="your_api_token_here"
चरण 1 — libcurl के साथ URL POST करें
एपीआई एक JSON बॉडी लेता है जो अभिनेता (unlocker.webunlocker) और इनपुट — लक्षित यूआरएल, विधि, और क्या जावास्क्रिप्ट को रेंडर करना है को नामित करता है। प्रमाणीकरण x-api-token हेडर है। libcurl प्रतिक्रिया को std::string में इकट्ठा करता है:
cpp
#include <curl/curl.h>
#include <string>
static size_t writeCb(char* ptr, size_t size, size_t nmemb, void* userdata) {
static_cast<std::string*>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
std::string fetchRendered(const std::string& url, const char* apiKey) {
std::string payload =
"{\"actor\":\"unlocker.webunlocker\",\"input\":{"
"\"url\":\"" + url + "\",\"method\":\"GET\","
"\"redirect\":true,\"js_render\":true}}";
CURL* curl = curl_easy_init();
std::string resp;
cpp
curl_slist* hdrs = nullptr;
hdrs = curl_slist_append(hdrs, "Content-Type: application/json");
hdrs = curl_slist_append(hdrs, (std::string("x-api-token: ") + apiKey).c_str());
curl_easy_setopt(curl, CURLOPT_URL, "https://api.scrapeless.com/api/v1/unlocker/request");
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hdrs);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 120L);
curl_easy_perform(curl);
curl_slist_free_all(hdrs);
curl_easy_cleanup(curl);
return resp;
}
js_render: true वह लोड-असर ध्वज है: यह एपीआई को कहता है कि पृष्ठ का जावास्क्रिप्ट चलाए और समाप्त डोम लौटाए, ताकि एक साइट जो अपने सामग्री को क्लाइंट-साइड बनाती है, असली मार्कअप के रूप में वापस आए।
अपनी API कुंजी मुफ्त योजना पर प्राप्त करें: app.scrapeless.com
चरण 2 — लिफाफे से HTML निकालें
एपीआई {"code":200,"data":"<html>…"} लौटाता है जिसमें HTML JSON-एस्केप किया गया है data में। एक छोटा एक्सट्रैक्टर उस क्षेत्र को अनएस्केप करता है — इस एक आकृति के लिए कोई भारी JSON पुस्तकालय की आवश्यकता नहीं है:
cpp
std::string jsonGetData(const std::string& body) {
const std::string key = "\"data\":\"";
size_t i = body.find(key);
if (i == std::string::npos) return "";
i += key.size();
std::string out;
for (; i < body.size(); ++i) {
char c = body[i];
if (c == '\\') { // अनएस्केप \" \\ \n \r \t \uXXXX
char n = body[++i];
if (n == 'n') out += '\n';
else if (n == 'r') out += '\r';
else if (n == 't') out += '\t';
else if (n == 'u') { out += (char)std::stoi(body.substr(i + 1, 4), nullptr, 16); i += 4; }
else out += n;
} else if (c == '"') break;
else out += c;
}
return out;
}
(कई क्षेत्र प्रकारों के लिए उत्पादन में, एक वास्तविक JSON पुस्तकालय से लिंक करें - लेकिन इस लिफाफे के लिए ऊपर का एक्सट्रैक्टर पर्याप्त है।)
चरण 3 — libxml2 और XPath के साथ पार्स करें
अब तेज़ भाग। libxml2 HTML को पार्स करता है; XPath ठीक उन नोड्स का चयन करता है जो आप चाहते हैं। यहाँ यह एक कैटलॉग पृष्ठ से उत्पाद शीर्षकों को खींचता है:
cpp
#include <libxml/HTMLparser.h>
#include <libxml/xpath.h>
#include <iostream>
void extractTitles(const std::string& html) {
htmlDocPtr doc = htmlReadMemory(html.c_str(), html.size(), nullptr, nullptr,
HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING);
xmlXPathContextPtr ctx = xmlXPathNewContext(doc);
xmlXPathObjectPtr r = xmlXPathEvalExpression(
(const xmlChar*)"//article[@class='product_pod']//h3/a/@title", ctx);
int n = r->nodesetval ? r->nodesetval->nodeNr : 0;
std::cout << "books=" << n << "\n";
for (int i = 0; i < n; ++i) {
xmlChar* t = xmlNodeGetContent(r->nodesetval->nodeTab[i]);
std::cout << t << "\n";
xmlFree(t);
}
xmlXPathFreeObject(r);
xmlXPathFreeContext(ctx);
xmlFreeDoc(doc);
}
चरण 4 — संकलित करें और चलाएँ
दोनों पुस्तकालयों से लिंक करें और संकलक को libxml2 हेडर की ओर इंगित करें:
bash
g++ scraper.cpp -o scraper -I/usr/include/libxml2 -lcurl -lxml2
./scraper
एक जावास्क्रिप्ट-निर्मित कैटलॉग पृष्ठ के खिलाफ एक लाइव रन ने वापस लौटाया:
text
http_status=200 html_bytes=51295 books=20
first_book=A Light in the Attic
यह पूरा लूप है: एक HTTPS POST आउट, 51 KB का रेंडर किए गए HTML वापस, libxml2 द्वारा पार्स किए गए 20 शीर्षक — कोई ब्राउज़र एंबेडेड नहीं, कोई प्रॉक्सी पूल नहीं, आपकी बाइनरी में कोई एंटी-बॉट कोड नहीं।
आपको क्या मिलता है
एपीआई लिफाफा छोटा और पूर्वानुमानित है:
json
{
"code": 200,
"data": "<html>...rendered DOM...</html>"
}
// एक लाइव कॉल से वास्तविक आकार। data JSON-एस्केप किए गए रेंडर किए गए HTML (सत्यापित रन में 51,295 बाइट) को रखता है।
कुछ ईमानदार अवलोकन:
js_render: trueलेटेंसी की कीमत चुकाता है लेकिन सामग्री खरीदता है। बिना इसे चालू किए स्थैतिक पृष्ठों के लिए इसे बंद कर दें; जब पृष्ठ बिना इसके रिक्त होता है, तो इसे चालू करें।- जटिल प्रतिक्रियाओं के लिए एक वास्तविक JSON पुस्तकालय का उपयोग करें। हाथ से बनाई गई एक्सट्रैक्टर एकल
dataक्षेत्र को संभालती है; कुछ समृद्ध सामान deserves एक उचित पार्सर। - XPath स्ट्रिंग-मैचिंग से बेहतर है। libxml2 का XPath किया गया हैंड-लिखित HTML स्कैनिंग की तुलना में तेज और अधिक मजबूत है।
- libxml2 ऑब्जेक्ट को मुक्त करें।
xmlFreeDoc,xmlXPathFreeContext,xmlXPathFreeObject— C++ आपके लिए ऐसा नहीं करेगा।
निष्कर्ष: पार्स करने के लिए C++, फेच के लिए एक API
प्रदर्शन-क्रिटिकल C++ स्क्रैपिंग तब सबसे अच्छा काम करता है जब C++ वही करता है जिसमें वह महान है - तेज़ पार्सिंग - और एक रेंडरिंग एपीआई उस हिस्से को संभालता है जो मूल रूप से बनाना दर्दनाक है: जावास्क्रिप्ट निष्पादन, प्रॉक्सी, और एंटी-बॉट हैंडलिंग। एक HTTPS POST के लिए libcurl और XPath निष्कर्षण के लिए libxml2 के साथ, पूरा क्लाइंट दो परिचित पुस्तकालयों और एकल g++ पंक्ति है। दूसरे भाषा में समान फेच-फिर-पार्स विभाजन के लिए, Scrapling + Scrapeless गाइड देखें; यूनिवर्सल स्क्रैपिंग API उत्पाद पृष्ठ और डॉक्स पूरी API को कवर करती हैं। जब पृष्ठ को इसकी आवश्यकता हो तो सर्वर-साइड पर रेंडर करें, XPath के साथ पार्स करें, और अपने libxml2 वस्तुओं को मुक्त करें।
क्या आप अपने AI-शक्ति डेटा पाइपलाइन का निर्माण करने के लिए तैयार हैं?
हमारे समुदाय में शामिल हों, एक मुफ्त योजना का दावा करें और उन डेवलपर्स से जुड़ें जो मूल स्क्रैपर्स बना रहे हैं: Discord · Telegram।
app.scrapeless.com पर मुफ्त runtime के लिए साइन अप करें और ऊपर दिए गए कार्यक्रम को उन साइटों और चयनकर्ताओं के अनुसार अनुकूलित करें जिनकी आपकी C++ पाइपलाइन को आवश्यकता है। मूल्य निर्धारण के लिए देखें।
प्रश्नोत्तर
प्र: क्यों न पूरे स्क्रैपर को शुद्ध C++ में libcurl के साथ सीधे साइट पर लिखें?
आप साधारण, असुरक्षित पृष्ठों के लिए कर सकते हैं। जिस पल एक लक्ष्य को जावास्क्रिप्ट रेंडरिंग, आवासीय IPs, या एंटी-बॉट हैंडलिंग की आवश्यकता होती है, उसे C++ में पुन: निर्माण करना एक बड़ा प्रोजेक्ट है। रेंडरिंग एपीआई को फेच करने से आपका बाइनरी छोटा रहता है।
प्र: क्या मुझे अपने C++ कार्यक्रम में एक हेडलेस ब्राउज़र चाहिए?
नहीं। js_render: true जावास्क्रिप्ट को सर्वर-साइड पर चलाता है और समाप्त DOM लौटाता है, इसलिए आपका C++ कोड केवल HTML पार्स करता है।
प्र: क्या libxml2 सही पार्सर है?
मानक के स्तर पर HTML के लिए, हाँ - यह तेज़, परिपक्व है, और इसमें पूर्ण XPath समर्थन है। यदि आप चाहें तो HTTP पक्ष के लिए CPR या Boost.Beast libcurl को बदल सकते हैं, लेकिन पार्सिंग के लिए libxml2 मानक विकल्प है।
प्र: मुझे बिना बड़े निर्भरता के JSON प्रतिक्रियाओं को कैसे संभालना है?
यहाँ दिखाए गए एकल data फ़ील्ड के लिए, एक छोटा एक्सट्रैक्तर ठीक है। समृद्ध प्रतिक्रियाओं के लिए, हाथ से पार्स करने के बजाय एक हल्की JSON पुस्तकालय को लिंक करें।
प्र: क्या मुझे प्रॉक्सी प्रबंधित करने की आवश्यकता है?
नहीं। API आवासीय प्रॉक्सियों के माध्यम से बाहर निकलता है; आप एक URL पास करते हैं और HTML वापस प्राप्त करते हैं।
प्र: मुझे libxml2 के साथ मेमोरी लीक से कैसे बचना है?
आप जो आवंटित करते हैं, उसे हमेशा मुक्त करें: xmlXPathFreeObject, xmlXPathFreeContext, और xmlFreeDoc। libxml2 मैन्युअल मेमोरी प्रबंधन का उपयोग करता है।
स्क्रैपलेस में, हम केवल सार्वजनिक रूप से उपलब्ध डेटा का उपयोग करते हैं, जबकि लागू कानूनों, विनियमों और वेबसाइट गोपनीयता नीतियों का सख्ती से अनुपालन करते हैं। इस ब्लॉग में सामग्री केवल प्रदर्शन उद्देश्यों के लिए है और इसमें कोई अवैध या उल्लंघन करने वाली गतिविधियों को शामिल नहीं किया गया है। हम इस ब्लॉग या तृतीय-पक्ष लिंक से जानकारी के उपयोग के लिए सभी देयता को कोई गारंटी नहीं देते हैं और सभी देयता का खुलासा करते हैं। किसी भी स्क्रैपिंग गतिविधियों में संलग्न होने से पहले, अपने कानूनी सलाहकार से परामर्श करें और लक्ष्य वेबसाइट की सेवा की शर्तों की समीक्षा करें या आवश्यक अनुमतियाँ प्राप्त करें।



