2014-10-17 3 views
5

इसलिए मैंने एचटीएमएल एजिलिटी पैक का उपयोग कर सी # में एक वेब साइट स्क्रैपर प्रोग्राम लिखा है। यह काफी सीधे आगे था। यहां तक ​​कि वेब पेज पर स्वरूपण में असंगतताओं के लिए लेखांकन, अभी भी मुझे काम करने के लिए केवल कुछ घंटे लग गए।मैं सी का उपयोग कर एक वेब पेज कैसे स्क्रैप करूं?

अब, मुझे इस प्रोग्राम को सी में फिर से कार्यान्वित करना है ताकि इसे लिनक्स वातावरण में चलाया जा सके। यह एक बड़ा दुःस्वप्न है।

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

यह इतना अच्छा काम नहीं किया है। एक्सएमएल लाइब्रेरी में मेरे पास एक्सेस है जो xpath का समर्थन नहीं करता है और मैं ऐसा करने में सक्षम नहीं हूं। इसलिए मैंने इच्छित डेटा को ढूंढने के लिए स्ट्रिंग मिलान का उपयोग करके पृष्ठ के माध्यम से पढ़ने का तरीका जानने का प्रयास किया है। मैं मदद नहीं कर सकता लेकिन महसूस करता हूं कि ऐसा करने का एक बेहतर तरीका होना चाहिए।

#define HTML_PAGE "codes.html" 

int extract() 
{ 

    FILE *html; 

    int found = 0; 
    char buffer[1000]; 
    char searchFor[80], *cp; 

    html = fopen(HTML_PAGE, "r"); 

    if (html) 
    { 

     // this is too error prone, if the buffer cuts off half way through a section of the string we are looking for, it will fail! 
     while(fgets(buffer, 999, html)) 
     { 
      trim(buffer); 

      if (!found) 
      { 
       sprintf(searchFor, "<strong>"); 
       cp = (char *)strstr(buffer, searchFor); 
       if(!cp)continue; 

       if (strncmp(cp + strlen(searchFor), "CO1", 3) == 0 || strncmp(cp + strlen(searchFor), "CO2", 3) == 0) 
       { 
        got_code(cp + strlen(searchFor)); 
       } 
      } 
     } 
    } 

    fclose(html); 

    return 0; 
} 

got_code(html) 
    char *html; 
{ 
    char code[8]; 
    char *endTag; 
    struct _code_st *currCode; 
    int i; 

    endTag = (char *)strstr(html, "</strong>"); 
    if(!endTag)return; 

    sprintf(code, "%.7s", html); 

    for(i=0 ; i<Data.Codes ; i++) 
     if(strcasecmp(Data.Code[i].Code, code)==0) 
      return; 

    ADD_TO_LIST(currCode, _code_st, Data.Code, Data.Codes); 
    currCode->Code = (char *)strdup(code); 

    printf("Code: %s\n", code); 
} 

ऊपर ठीक से काम नहीं करता है:

यहाँ मैं क्या है। मुझे बहुत सारे कोड मिलते हैं जिनमें मुझे रूचि है, लेकिन जैसा कि मैंने ऊपर उल्लेख किया है, अगर बफर गलत स्पॉट्स पर कट ऑफ करता है तो मुझे कुछ याद आती है।

मैंने एचटीएमएल के पूरे हिस्से को पढ़ने की कोशिश की, मुझे एक स्ट्रिंग में रूचि है, लेकिन मैं यह समझने में सक्षम नहीं था कि उसके माध्यम से कैसे चक्र करना है - मुझे कोई कोड प्रदर्शित नहीं हो सका।

क्या कोई जानता है कि मैं इस मुद्दे को कैसे हल कर सकता हूं?

संपादित करें: मैं इसके बारे में कुछ और सोच रहा हूं। क्या मैं फ़ाइल में आगे बढ़ सकता हूं और पाठ के प्रत्येक 'ब्लॉक' के अंत की खोज कर रहा हूं, जिसे मैं पार्स कर रहा हूं और बफर आकार को सेट करने से पहले इसे सेट कर सकता हूं? क्या मुझे एक ही फ़ाइल में एक और फ़ाइल सूचक की आवश्यकता होगी? यह (उम्मीद है) असुविधाजनक स्थानों पर बफर काटने की समस्या को रोक देगा।

+0

शायद इसे मोनो के साथ चलाएं? –

+5

सी बहुत अच्छा है, लेकिन इस तरह के कार्य के लिए नहीं। इसके बजाय पर्ल या पायथन की तरह कुछ और उपयोग करें। नरक, यहां तक ​​कि PHP भी करेंगे। –

+0

हाँ, मुझे सहमत होना है। यह सिर्फ नौकरी के लिए गलत उपकरण की तरह लगता है। –

उत्तर

5

ठीक है, तो दीवार के ऊपर सिर के बहुत अधिक टक्कर के बाद मेरे ऊपर कोड काम करने के तरीके के साथ आने का प्रयास करने के बाद, मैंने थोड़ा अलग दृष्टिकोण करने का फैसला किया।

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

#define HTML_PAGE "codes.html" 
#define START_BLOCK "<strong>" 
#define END_BLOCK "</strong>" 

int extract() 
{ 

    FILE *html; 

    int found = 0; 
    char *line = NULL, *endTag, *startTag; 
    size_t len = 0; 
    ssize_t read; 

    char searchFor[80]; 

    html = fopen(HTML_PAGE, "r"); 

    if (html) 
    { 
     while((read = getline(&line, &len, html)) != -1) 
     { 
      if (found) // found line with codes we are interested in 
      { 
       char *ptr = line; 
       size_t nlen = strlen (END_BLOCK); 

       while (ptr != NULL) 
       { 
        sprintf(searchFor, START_BLOCK); 
        startTag = (char *)strstr(ptr, searchFor); 
        if(!startTag) 
        { 
         nlen = strlen (START_BLOCK); 
         ptr += nlen; 
         continue; 
        } 

        if (strncmp(startTag + strlen(searchFor), "CO1", 3) == 0 || strncmp(startTag + strlen(searchFor), "CO2", 3) == 0) 
         got_code(startTag + strlen(searchFor), code); 
        else { 
         nlen = strlen (START_BLOCK); 
         ptr += nlen; 
         continue; 
        } 

        sprintf(searchFor, END_BLOCK); 
        ptr = (char *)strstr(ptr, searchFor); 

        if (!ptr) { found = 0; break; } 

        nlen = strlen (END_BLOCK);     
        ptr += nlen; 

        if (ptr) 
        { 
         // look ahead to make sure we have more to pull out 
         sprintf(searchFor, END_BLOCK); 
         endTag = (char *)strstr(ptr, searchFor); 
         if (!endTag) { break; } 
        } 
       } 

       found = 0; 
       break; 
      } 

      // find the section of the downloaded page we care about 
      // the next line we read will be a blob containing the html we want 
      if (strstr(line, "wiki-content") != NULL) 
      { 
       found = 1; 
      } 
     } 

     fclose(html); 
    } 

    return 0; 
} 

got_code(char *html) 
{ 
    char code[8]; 
    char *endTag; 
    struct _code_st *currCode; 
    int i; 

    endTag = (char *)strstr(html, "</strong>"); 
    if(!endTag)return; 

    sprintf(code, "%.7s", html); 

    for(i=0 ; i<Data.Codes ; i++) 
     if(strcasecmp(Data.Code[i].Code, code)==0) 
      return; 

    ADD_TO_LIST(currCode, _code_st, Data.Code, Data.Codes); 
    currCode->Code = (char *)strdup(code); 

    printf("Code: %s\n", code); 
} 

लगभग के रूप में सुरुचिपूर्ण या मेरे सी # कार्यक्रम के रूप में मजबूत लेकिन नहीं कम से कम इसे वापस खींचती सभी जानकारी मैं चाहता हूँ:

यहाँ मेरी कोड (जो बदसूरत लेकिन कार्यात्मक है)।

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