2009-03-14 27 views
6

मैं एक साक्षात्कार के लिए कुछ प्रश्नोत्तरी प्रश्नों का उत्तर दे रहा था, और सवाल यह था कि मैं स्क्रीन स्क्रैपिंग कैसे करूं। यही है, एक वेब पेज से सामग्री चुनना, मान लीजिए कि आपके पास सीधे जानकारी पूछने के लिए एक बेहतर संरचित तरीका नहीं है (उदा। एक वेब सेवा)।स्क्रीन स्क्रैपिंग: नियमित अभिव्यक्तियां या XQuery अभिव्यक्तियां?

मेरा समाधान XQuery अभिव्यक्ति का उपयोग करना था। अभिव्यक्ति काफी लंबी थी क्योंकि मुझे आवश्यक सामग्री HTML पदानुक्रम में बहुत गहरी थी। id विशेषता के साथ तत्व प्राप्त करने से पहले मुझे पूर्वजों के माध्यम से एक उचित तरीके से खोजना पड़ा। उदाहरण के लिए, उत्पाद आयाम के लिए एक Amazon.com पेज स्क्रैप इस तरह दिखता है:

//a[@id="productDetails"] 
/following-sibling::table 
//h2[contains(child::text(), "Product Details")] 
/following-sibling::div 
//li 
/b[contains(child::text(), "Product Dimensions:")] 
/following-sibling::text() 

एक बहुत बुरा अभिव्यक्ति है कि है, लेकिन यही कारण है कि अमेज़न एक वेब सेवा एपीआई प्रदान करता है। वैसे भी, यह सिर्फ एक उदाहरण है। सवाल अमेज़ॅन के बारे में नहीं था, यह स्क्रीन स्क्रैपिंग के बारे में है।

साक्षात्कारकर्ता को मेरे समाधान को पसंद नहीं आया। उन्होंने सोचा कि यह नाजुक था, क्योंकि अमेज़ॅन द्वारा पेज डिज़ाइन में बदलाव को XQuery अभिव्यक्ति को फिर से लिखने की आवश्यकता हो सकती है। एक XQuery अभिव्यक्ति को डिबग करना जो पृष्ठ पर किसी भी चीज़ से मेल नहीं खाता है, यह कठिन है।

मैं उनके बयान से असहमत नहीं था, लेकिन मुझे नहीं लगता था कि उनका समाधान कोई सुधार था: उन्होंने सोचा कि नियमित अभिव्यक्ति का उपयोग करना बेहतर है, और शिपिंग वजन के पास सामग्री और मार्कअप की खोज करें। उदाहरण के लिए, पर्ल का उपयोग कर:

$html =~ m{<li>\s*<b>\s*Product Dimensions:\s*</b>\s*(.*?)</li>}s; 

मेरे जवाबी तर्क था कि यह भी अमेज़न अपने एचटीएमएल कोड को बदलने के लिए अतिसंवेदनशील है। वे राजधानियों में एचटीएमएल टैग (<LI>) का जादू कर सकते हैं, या सीएसएस विशेषताओं को जोड़ सकते हैं या <b> को <span> में बदल सकते हैं या "उत्पाद आयाम:" से "आयाम:" या कई अन्य प्रकार के परिवर्तनों को लेबल बदल सकते हैं। मेरा मुद्दा यह था कि नियमित अभिव्यक्ति मेरे XQuery समाधान में बुलाए गए कमजोरियों को हल नहीं करती है।

लेकिन इसके अतिरिक्त, नियमित अभिव्यक्ति झूठी सकारात्मक पा सकते हैं, जब तक आप अभिव्यक्ति में पर्याप्त संदर्भ नहीं जोड़ते। यह अनजाने में ऐसी सामग्री से मेल खा सकता है जो किसी टिप्पणी, या एक विशेषता स्ट्रिंग या सीडीएटीए अनुभाग के अंदर होता है।

मेरा सवाल है, स्क्रीन स्क्रैपिंग करने के लिए आप किस तकनीक का उपयोग करते हैं? आपने उस समाधान का चयन क्यों किया? क्या इसका उपयोग करने के लिए कुछ अनिवार्य कारण है? या कभी दूसरे का उपयोग नहीं करते? क्या ऊपर दिखाए गए लोगों के अलावा कोई तीसरी पसंद है?

पीएस: तर्क के लिए मान लें कि कोई वेब सेवा API नहीं है या वांछित सामग्री प्राप्त करने के लिए अन्य प्रत्यक्ष तरीका नहीं है।

उत्तर

3

मैनेजर के कारणों के लिए, मैं नियमित अभिव्यक्ति का उपयोग करता हूं, कुछ (अधिक पोर्टेबल, बाहरी प्रोग्रामर के लिए आसान, आदि के लिए आसान) लगाएं।

आपका काउंटर तर्क का कहना है कि उनके समाधान स्थानीय परिवर्तन के संबंध में कमजोर था, जबकि तुम्हारा वैश्विक परिवर्तन के संबंध में कमजोर है याद करते हैं। जो कुछ भी उसकी इच्छा को तोड़ता है वह शायद तुम्हारा तोड़ देगा, लेकिन वीजा-विपरीत नहीं।

अंत में, अपने समाधान में ढलान/फ्लेक्स बनाने के लिए बहुत आसान है (उदाहरण के लिए, आपको इनपुट में कई मामूली विविधताओं से निपटना होगा)।

4

मैं नियमित अभिव्यक्ति का उपयोग करता हूं, लेकिन केवल इसलिए कि अधिकांश HTML पृष्ठ मान्य XML नहीं हैं, इसलिए आपको XQUERY को काम करने के लिए कभी भी नहीं मिलेगा।

मुझे XQuery नहीं पता, लेकिन यह मुझे XPATH अभिव्यक्ति की तरह दिखता है। यदि ऐसा है, तो इसमें बहुत सारे "//" ऑपरेटरों के साथ थोड़ा महंगा लगता है।

+0

एक्सएमएल-आधारित वेब स्क्रैपिंग से बचने का यह मुख्य कारण है। कोई एक्सएमएल प्रोसेसर ब्राउज़र के रूप में क्षमा नहीं कर रहा है। XQuery को पूरी तरह से बेकार प्रस्तुत करने के लिए पृष्ठ को केवल एक अच्छी तरह से गठित नियम को तोड़ने की आवश्यकता है। – harpo

1

मुझे वास्तव में सीएसएस खोज अभिव्यक्तियों को पढ़ने के लिए आसान लगता है। आपकी पसंद की भाषा में कम से कम एक लाइब्रेरी मौजूद है जो एक पृष्ठ का विश्लेषण करेगी और आपको विशेष तत्वों का पता लगाने के लिए सीएसएस निर्देश लिखने की अनुमति देगी। यदि पास के पास उपयुक्त वर्ग या आईडी हुक है तो अभिव्यक्ति बहुत छोटी है। अन्यथा, उन तत्वों को पकड़ें जो उपयुक्त लगते हैं और जिनकी आपको आवश्यकता होती है उन्हें ढूंढने के लिए पुन: प्रयास करें।

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

1

स्क्रीन-स्क्रैपिंग के लिए एक गैर-भंगुर समाधान? इसके लिए साक्षात्कारकर्ता को शुभकामनाएं: सिर्फ इसलिए कि नियमित अभिव्यक्तियों ने बहुत सारे संदर्भों को दूर कर दिया है इसका मतलब यह नहीं है कि वे कम भंगुर हैं: बस वे अन्य तरीकों से भंगुर हैं। बेईमानी भी कोई कमी नहीं हो सकती है: यदि स्रोत वेब पेज में कुछ बदलाव होता है, तो यदि आपका समाधान एक चालाक (और अप्रत्याशित) तरीके से क्षतिपूर्ति करने की कोशिश करने के बजाय अलार्म उठाता है तो आप अक्सर बेहतर होते हैं। जैसा कि आपने नोट किया था। ये चीजें हमेशा आपकी धारणाओं पर निर्भर करती हैं: इस मामले में, संभावित परिवर्तन का गठन किस पर होता है।

मैं HTML agility pack के शौकीन हूं: आपको एक्सपीएथ की अभिव्यक्तिशील शक्ति के साथ संयुक्त गैर-एक्सएचटीएमएल-अनुरूप वेब पेजों की सहिष्णुता मिलती है।

2

जेटीडी या सुंदर सूप मेरे लिए ठीक काम करता है। निश्चित रूप से // XPATH एक्सपर्सन स्क्रैप करने के लिए काफी महंगा है।

1

नियमित अभिव्यक्ति वास्तव में तेज़ हैं और गैर एक्सएमएल दस्तावेज़ों के साथ काम करते हैं। वे XQuery के खिलाफ वास्तव में अच्छे अंक हैं। हालांकि मुझे लगता है कि साफ और शायद कुछ हद तक सरल XQuery तरह एक्सएचटीएमएल करने के लिए कुछ कनवर्टर का उपयोग करते हुए, तुम्हारा से केवल अंतिम भाग की तरह:

//b[contains(child::text(), "Product Dimensions:")]/following-sibling::text() 

एक बहुत अच्छा विकल्प नहीं है।

सादर,

Rafal Rusin

1

एचटीएमएल पृष्ठों पर काम करने के लिए, यह सबसे अच्छा HTMLAgilityPack उपयोग करने के लिए (और कुछ Linq कोड के साथ) है। यह सभी तत्वों के माध्यम से विश्लेषण करने और/या XPath के साथ सीधी खोज करने का एक शानदार तरीका है। मेरी राय में, यह RegEx से अधिक सटीक है और प्रोग्राम के लिए आसान है। मैं पहले इसका उपयोग करने के लिए थोड़ा अनिच्छुक था, लेकिन यह आपके प्रोजेक्ट में जोड़ना बहुत आसान है और मुझे लगता है कि एचटीएमएल के साथ काम करने के लिए डी कारक मानक है। http://htmlagilitypack.codeplex.com/

शुभकामनाएं!

+0

धन्यवाद, हां, एचटीएमएल एजिलिटी पैक को पोंटस गैग द्वारा एक और जवाब में सुझाव दिया गया था। मुझे आश्चर्य है कि एचटीएमएल एजिलिटी पैक आंतरिक रूप से उपयोग करता है - XPath, नियमित अभिव्यक्ति, या कुछ अन्य कस्टम डोम पार्सिंग या कुछ और। –

+1

HtmlAgilityPack के साथ, आप दस्तावेज़ Dode.ChildNodes के माध्यम से पूरे DOM के माध्यम से जा सकते हैं। उदाहरण के लिए: voMyHTML.DocumentNode में प्रत्येक voTag के लिए।ChildNodes या आप voMyHTML.DocumentNode.SelectSingleNode (vsXPath) के साथ एक एकल नोड में ज़ूम कर सकते हैं या आप भी उपयोग कर सकते हैं LINQ: voElements = (voTag से voMyHTML.DocumentNode.ChildNodes में कहाँ voTag.GetAttributeValue ("वर्ग") = "myClass" voTag का चयन करें) –

संबंधित मुद्दे