2012-05-17 17 views
7

में दिलचस्पी है, इसलिए मुझे this theory में दिलचस्पी है कि यदि आप यादृच्छिक विकिपीडिया आलेख पर जाते हैं, तो पहले लिंक को बार-बार ब्रांड्स के अंदर नहीं क्लिक करें, 95% मामलों में आप समाप्त हो जाएंगे लेख पर Philosophy पर।एक विकिपीडिया आलेख में पहला लिंक प्राप्त करें, जो कि

मैं अजगर उस लिंक मेरे लिए और अंत में प्राप्त करने में कठिनाई करता है में एक पटकथा लिखने के, एक अच्छा सूची जिनमें से लेख दौरा किया गया (linkA -> linkB -> linkC) आदि प्रिंट चाहते थे

मैं का HTML डोम पाने में कामयाब रहे वेब पेज, और कुछ अनावश्यक लिंक और शीर्ष विवरण पट्टी को बाहर करने में कामयाब रहे जो असंबद्धता पृष्ठों का नेतृत्व करता है। अब तक मैंने निष्कर्ष निकाला है कि:

  • डोम तालिका के साथ शुरू होता है जो आप कुछ पृष्ठों पर दाईं ओर देखते हैं, उदाहरण के लिए Human में। हम इन लिंक को अनदेखा करना चाहते हैं।
  • मान्य लिंक तत्वों सब अगर यह एक <b> टैग के अंदर या इसी तरह की है उनके पूर्वज (अक्सर माता-पिता या दादा-दादी के रूप में कहीं न कहीं एक <p> तत्व है। शीर्ष पट्टी जो बहुविकल्पी पृष्ठों की ओर जाता है, किसी भी <p> तत्व होते प्रतीत नहीं होता है।
  • अमान्य लिंक उसके बाद एक कॉलन कुछ विशेष शब्द होते जैसे Wikipedia:

अब तक तो अच्छा लेकिन। वह कोष्ठकों में है कि मुझे मिलता है। लेख Human के बारे में उदाहरण के लिए, पहली कड़ी नहीं अंदर कोष्ठक में है "/ विकी/प्रजाति", लेकिन लिपि को "/ विकी/वर्गीकरण" मिलती है जो उनके अंदर है।

मुझे नहीं पता कि इस प्रोग्रामेटिक तरीके से कैसे जाना है, क्योंकि मुझे माता-पिता/बच्चे नोड्स के कुछ संयोजन में टेक्स्ट देखना है जो हमेशा एक जैसा नहीं हो सकता है। कोई विचार?

मेरा कोड नीचे देखा जा सकता है, लेकिन यह ऐसा कुछ है जिसे मैंने वास्तव में जल्दी बनाया और बहुत गर्व नहीं किया। हालांकि, इस पर टिप्पणी की गई है, तो आप मेरी विचारों की रेखा देख सकते हैं (मुझे उम्मीद है :))।

"""Wikipedia fun""" 
import urllib2 
from xml.dom.minidom import parseString 
import time 

def validWikiArticleLinkString(href): 
    """ Takes a string and returns True if it contains the substring 
     '/wiki/' in the beginning and does not contain any of the 
     "special" wiki pages. 
    """ 
    return (href.find("/wiki/") == 0 
      and href.find("(disambiguation)") == -1 
      and href.find("File:") == -1 
      and href.find("Wikipedia:") == -1 
      and href.find("Portal:") == -1 
      and href.find("Special:") == -1 
      and href.find("Help:") == -1 
      and href.find("Template_talk:") == -1 
      and href.find("Template:") == -1 
      and href.find("Talk:") == -1 
      and href.find("Category:") == -1 
      and href.find("Bibcode") == -1 
      and href.find("Main_Page") == -1) 


if __name__ == "__main__": 
    visited = [] # a list of visited links. used to avoid getting into loops 

    opener = urllib2.build_opener() 
    opener.addheaders = [('User-agent', 'Mozilla/5.0')] # need headers for the api 

    currentPage = "Human" # the page to start with 

    while True: 
     infile = opener.open('http://en.wikipedia.org/w/index.php?title=%s&printable=yes' % currentPage) 
     html = infile.read() # retrieve the contents of the wiki page we are at 

     htmlDOM = parseString(html) # get the DOM of the parsed HTML 
     aTags = htmlDOM.getElementsByTagName("a") # find all <a> tags 

     for tag in aTags: 
      if "href" in tag.attributes.keys():   # see if we have the href attribute in the tag 
       href = tag.attributes["href"].value  # get the value of the href attribute 
       if validWikiArticleLinkString(href):        # if we have one of the link types we are looking for 

        # Now come the tricky parts. We want to look for links in the main content area only, 
        # and we want the first link not in parentheses. 

        # assume the link is valid. 
        invalid = False    

        # tables which appear to the right on the site appear first in the DOM, so we need to make sure 
        # we are not looking at a <a> tag somewhere inside a <table>. 
        pn = tag.parentNode      
        while pn is not None: 
         if str(pn).find("table at") >= 0: 
          invalid = True 
          break 
         else: 
          pn = pn.parentNode 

        if invalid:  # go to next link 
         continue    

        # Next we look at the descriptive texts above the article, if any; e.g 
        # This article is about .... or For other uses, see ... (disambiguation). 
        # These kinds of links will lead into loops so we classify them as invalid. 

        # We notice that this text does not appear to be inside a <p> block, so 
        # we dismiss <a> tags which aren't inside any <p>. 
        pnode = tag.parentNode 
        while pnode is not None: 
         if str(pnode).find("p at") >= 0: 
          break 
         pnode = pnode.parentNode 
        # If we have reached the root node, which has parentNode None, we classify the 
        # link as invalid. 
        if pnode is None: 
         invalid = True 

        if invalid: 
         continue 


        ###### this is where I got stuck: 
        # now we need to look if the link is inside parentheses. below is some junk 

#     for elem in tag.parentNode.childNodes: 
#      while elem.firstChild is not None: 
#       elem = elem.firstChid 
#      print elem.nodeValue 

        print href  # this will be the next link 
        newLink = href[6:] # except for the /wiki/ part 
        break 

     # if we have been to this link before, break the loop 
     if newLink in visited: 
      print "Stuck in loop." 
      break 
     # or if we have reached Philosophy 
     elif newLink == "Philosophy": 
      print "Ended up in Philosophy." 
      break 
     else: 
      visited.append(currentPage)  # mark this currentPage as visited 
      currentPage = newLink   # make the the currentPage we found the new page to fetch 
      time.sleep(5)     # sleep some to see results as debug 
+2

आप lxml द्वारा प्रदान किए गए समृद्ध इंटरफ़ेस को आजमा सकते हैं। यह आपको xpath, और अन्य चीजों का एक समूह का उपयोग करने की अनुमति देता है। – Marcin

+6

जबकि हम अनुशंसाओं पर हैं, मैं यहां सुंदरसप को शायद एक उपयोगी नाम के रूप में छोड़ना चाहता हूं। – marue

+3

@marue दो महान स्वाद जो एक साथ महान स्वाद लेते हैं: lxml में एक सुंदरसप बैकएंड है! – Marcin

उत्तर

3

मैं इस खेल को खेलने के लिए Github (http://github.com/JensTimmerman/scripts/blob/master/philosophy.py) पर एक अजगर स्क्रिप्ट नहीं मिली। यह HTML पार्सिंग के लिए सुंदरसप का उपयोग करता है और पैराथेसिस समस्या से निपटने के लिए वह लिंक को पार्स करने से पहले ब्रैकेट के बीच टेक्स्ट हटा देता है।

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