2010-12-07 18 views
19

मुझे वेब से खनन सामग्री के लिए एक शक्तिशाली वेब स्क्रैपर लाइब्रेरी की आवश्यकता है। भुगतान किया जा सकता है या मुफ्त दोनों मेरे लिए ठीक हो जाएगा। कृपया मुझे अपने पसंदीदा डेटाबेस में डेटा और स्टोर खनन के लिए एक लाइब्रेरी या बेहतर तरीका सुझाएं। मैंने खोज की है लेकिन मुझे इसके लिए कोई अच्छा समाधान नहीं मिला। मुझे विशेषज्ञों से एक अच्छा सुझाव चाहिए। कृपया मेरी मदद करें।मुझे एक शक्तिशाली वेब स्क्रैपर लाइब्रेरी की आवश्यकता है

+7

बस चेतावनी का एक शब्द: साइट को स्क्रैप करने पर साइट को स्क्रैप करने पर चेतावनी के बिना अपने एचटीएमएल को काफी हद तक बदल सकता है। एक दिन आपको वह सामग्री मिलती है जहां आप इसकी अपेक्षा करते हैं; अगले दिन उन्होंने एक डीवीवी या कुछ के साथ एक HTML तालिका को बदल दिया है। आकस्मिक योजना होने के लिए यह एक अच्छा विचार है, और आप तेजी से संशोधित करने में सक्षम होने के लिए कैसे/क्या स्क्रैप कर रहे हैं। –

उत्तर

16

स्क्रैपिंग वास्तव में आसान है, आपको केवल उस सामग्री को पार्स करना है जिसे आप डाउनलोड कर रहे हैं और सभी संबंधित लिंक प्राप्त करें।

सबसे महत्वपूर्ण टुकड़ा हालांकि वह हिस्सा है जो HTML को संसाधित करता है। चूंकि अधिकतर ब्राउज़रों को प्रस्तुत करने के लिए सबसे स्वच्छ (या मानकों-अनुरूप) HTML की आवश्यकता नहीं होती है, इसलिए आपको एक HTML पार्सर की आवश्यकता होती है जो HTML की समझ में सक्षम होने जा रहा है जो हमेशा अच्छी तरह से गठित नहीं होता है।

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

इसके अलावा, आपको बस अपने संसाधित डेटा को पकड़ने के लिए डेटा स्टोर चुनना होगा (आप इसके लिए किसी भी डेटाबेस तकनीक का उपयोग कर सकते हैं) और वेब से सामग्री डाउनलोड करने का एक तरीका, जो .NET दो उच्च स्तरीय तंत्र प्रदान करता है , WebClient और HttpWebRequest/HttpWebResponse कक्षाएं।

+7

कृपया प्यार के लिए। किसी शक्तिशाली व्यक्ति वेब स्क्रैपर की आवश्यकता वाले किसी के लिए WebClient/HttpWebRequest/HttpWebResponse के उपयोग का सुझाव न दें! वह सिर्फ कुछ सॉकेट लिखने और सभी डेटा लोड करने के बेहतर होगा। – CodingBarfield

+7

@ बरफील्डएमवी: मैं वेब क्लाइंट का प्रशंसक नहीं हूं, क्योंकि यह बहुत उच्च स्तर है, सॉकेट्स आईएमओ का उपयोग निम्न स्तर से नीचे है; यह आपको अनुरोध/प्रतिक्रिया करने के लिए केवल एक अच्छा सौदा लागू करने के लिए मजबूर करता है, जबकि HttpWebRequest/HttpWebResponse में अधिकांश कार्यक्षमता है जिसमें किसी को कुछ बुद्धिमान क्रॉलर (कुकी समर्थन, हेडर संग्रह इत्यादि) में बनाया जाना चाहिए। – casperOne

+1

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

1

मेरे सलाह:

आप एक HTML पार्सर के लिए चारों ओर देखने सकते हैं और फिर इसका इस्तेमाल साइटों से जानकारी पार्स आउट कर। (here की तरह)। फिर आपको बस इतना करना होगा कि उस डेटा को अपने डेटाबेस में सहेजें, हालांकि आप फिट देखते हैं।

मैंने अपना खुद का स्क्रैपर कुछ बार बनाया है, यह बहुत आसान है और आपको सहेजे गए डेटा को कस्टमाइज़ करने की अनुमति देता है।

डाटा माइनिंग उपकरण

आप वास्तव में सिर्फ यह करने के लिए एक उपकरण प्राप्त करने के लिए तो आप कोई समस्या नहीं होनी चाहिए finding some चाहते हैं।

2

सरल वेबसाइटों के लिए (= केवल सादा HTML), मैकेनाइजेशन वास्तव में अच्छी तरह से और तेज़ काम करता है। जावास्क्रिप्ट, AJAX या यहां तक ​​कि फ्लैश का उपयोग करने वाली साइटों के लिए, आपको iMacros जैसे वास्तविक ब्राउज़र समाधान की आवश्यकता है।

6
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace SoftCircuits.Parsing 
{ 
    public class HtmlTag 
    { 
     /// <summary> 
     /// Name of this tag 
     /// </summary> 
     public string Name { get; set; } 

     /// <summary> 
     /// Collection of attribute names and values for this tag 
     /// </summary> 
     public Dictionary<string, string> Attributes { get; set; } 

     /// <summary> 
     /// True if this tag contained a trailing forward slash 
     /// </summary> 
     public bool TrailingSlash { get; set; } 

     /// <summary> 
     /// Indicates if this tag contains the specified attribute. Note that 
     /// true is returned when this tag contains the attribute even when the 
     /// attribute has no value 
     /// </summary> 
     /// <param name="name">Name of attribute to check</param> 
     /// <returns>True if tag contains attribute or false otherwise</returns> 
     public bool HasAttribute(string name) 
     { 
      return Attributes.ContainsKey(name); 
     } 
    }; 

    public class HtmlParser : TextParser 
    { 
     public HtmlParser() 
     { 
     } 

     public HtmlParser(string html) : base(html) 
     { 
     } 

     /// <summary> 
     /// Parses the next tag that matches the specified tag name 
     /// </summary> 
     /// <param name="name">Name of the tags to parse ("*" = parse all tags)</param> 
     /// <param name="tag">Returns information on the next occurrence of the specified tag or null if none found</param> 
     /// <returns>True if a tag was parsed or false if the end of the document was reached</returns> 
     public bool ParseNext(string name, out HtmlTag tag) 
     { 
      // Must always set out parameter 
      tag = null; 

      // Nothing to do if no tag specified 
      if (String.IsNullOrEmpty(name)) 
       return false; 

      // Loop until match is found or no more tags 
      MoveTo('<'); 
      while (!EndOfText) 
      { 
       // Skip over opening '<' 
       MoveAhead(); 

       // Examine first tag character 
       char c = Peek(); 
       if (c == '!' && Peek(1) == '-' && Peek(2) == '-') 
       { 
        // Skip over comments 
        const string endComment = "-->"; 
        MoveTo(endComment); 
        MoveAhead(endComment.Length); 
       } 
       else if (c == '/') 
       { 
        // Skip over closing tags 
        MoveTo('>'); 
        MoveAhead(); 
       } 
       else 
       { 
        bool result, inScript; 

        // Parse tag 
        result = ParseTag(name, ref tag, out inScript); 
        // Because scripts may contain tag characters, we have special 
        // handling to skip over script contents 
        if (inScript) 
         MovePastScript(); 
        // Return true if requested tag was found 
        if (result) 
         return true; 
       } 
       // Find next tag 
       MoveTo('<'); 
      } 
      // No more matching tags found 
      return false; 
     } 

     /// <summary> 
     /// Parses the contents of an HTML tag. The current position should be at the first 
     /// character following the tag's opening less-than character. 
     /// 
     /// Note: We parse to the end of the tag even if this tag was not requested by the 
     /// caller. This ensures subsequent parsing takes place after this tag 
     /// </summary> 
     /// <param name="reqName">Name of the tag the caller is requesting, or "*" if caller 
     /// is requesting all tags</param> 
     /// <param name="tag">Returns information on this tag if it's one the caller is 
     /// requesting</param> 
     /// <param name="inScript">Returns true if tag began, and did not end, and script 
     /// block</param> 
     /// <returns>True if data is being returned for a tag requested by the caller 
     /// or false otherwise</returns> 
     protected bool ParseTag(string reqName, ref HtmlTag tag, out bool inScript) 
     { 
      bool doctype, requested; 
      doctype = inScript = requested = false; 

      // Get name of this tag 
      string name = ParseTagName(); 

      // Special handling 
      if (String.Compare(name, "!DOCTYPE", true) == 0) 
       doctype = true; 
      else if (String.Compare(name, "script", true) == 0) 
       inScript = true; 

      // Is this a tag requested by caller? 
      if (reqName == "*" || String.Compare(name, reqName, true) == 0) 
      { 
       // Yes 
       requested = true; 
       // Create new tag object 
       tag = new HtmlTag(); 
       tag.Name = name; 
       tag.Attributes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); 
      } 

      // Parse attributes 
      MovePastWhitespace(); 
      while (Peek() != '>' && Peek() != NullChar) 
      { 
       if (Peek() == '/') 
       { 
        // Handle trailing forward slash 
        if (requested) 
         tag.TrailingSlash = true; 
        MoveAhead(); 
        MovePastWhitespace(); 
        // If this is a script tag, it was closed 
        inScript = false; 
       } 
       else 
       { 
        // Parse attribute name 
        name = (!doctype) ? ParseAttributeName() : ParseAttributeValue(); 
        MovePastWhitespace(); 
        // Parse attribute value 
        string value = String.Empty; 
        if (Peek() == '=') 
        { 
         MoveAhead(); 
         MovePastWhitespace(); 
         value = ParseAttributeValue(); 
         MovePastWhitespace(); 
        } 
        // Add attribute to collection if requested tag 
        if (requested) 
        { 
         // This tag replaces existing tags with same name 
         if (tag.Attributes.ContainsKey(name)) 
          tag.Attributes.Remove(name); 
         tag.Attributes.Add(name, value); 
        } 
       } 
      } 
      // Skip over closing '>' 
      MoveAhead(); 

      return requested; 
     } 

     /// <summary> 
     /// Parses a tag name. The current position should be the first character of the name 
     /// </summary> 
     /// <returns>Returns the parsed name string</returns> 
     protected string ParseTagName() 
     { 
      int start = Position; 
      while (!EndOfText && !Char.IsWhiteSpace(Peek()) && Peek() != '>') 
       MoveAhead(); 
      return Substring(start, Position); 
     } 

     /// <summary> 
     /// Parses an attribute name. The current position should be the first character 
     /// of the name 
     /// </summary> 
     /// <returns>Returns the parsed name string</returns> 
     protected string ParseAttributeName() 
     { 
      int start = Position; 
      while (!EndOfText && !Char.IsWhiteSpace(Peek()) && Peek() != '>' && Peek() != '=') 
       MoveAhead(); 
      return Substring(start, Position); 
     } 

     /// <summary> 
     /// Parses an attribute value. The current position should be the first non-whitespace 
     /// character following the equal sign. 
     /// 
     /// Note: We terminate the name or value if we encounter a new line. This seems to 
     /// be the best way of handling errors such as values missing closing quotes, etc. 
     /// </summary> 
     /// <returns>Returns the parsed value string</returns> 
     protected string ParseAttributeValue() 
     { 
      int start, end; 
      char c = Peek(); 
      if (c == '"' || c == '\'') 
      { 
       // Move past opening quote 
       MoveAhead(); 
       // Parse quoted value 
       start = Position; 
       MoveTo(new char[] { c, '\r', '\n' }); 
       end = Position; 
       // Move past closing quote 
       if (Peek() == c) 
        MoveAhead(); 
      } 
      else 
      { 
       // Parse unquoted value 
       start = Position; 
       while (!EndOfText && !Char.IsWhiteSpace(c) && c != '>') 
       { 
        MoveAhead(); 
        c = Peek(); 
       } 
       end = Position; 
      } 
      return Substring(start, end); 
     } 

     /// <summary> 
     /// Locates the end of the current script and moves past the closing tag 
     /// </summary> 
     protected void MovePastScript() 
     { 
      const string endScript = "</script"; 

      while (!EndOfText) 
      { 
       MoveTo(endScript, true); 
       MoveAhead(endScript.Length); 
       if (Peek() == '>' || Char.IsWhiteSpace(Peek())) 
       { 
        MoveTo('>'); 
        MoveAhead(); 
        break; 
       } 
      } 
     } 
    } 
} 
संबंधित मुद्दे