2016-06-04 6 views
-3

Um Trainingsdaten zu erhalten, schrieb ich einen Crawler, um die Top 500 Websites auf Alexa mit einer Tiefe von 2 zu verfolgen und alle gefundenen Links in eine Datei zu schreiben. Im Moment sucht es nach allen Links im HTML und schreibt sie in eine Datei. Das Problem ist, dass der Crawler alle Links zu Anzeigen vermisst, von denen sich einige in Iframes befinden oder sich in CSS-Dateien befinden. Wie kann ich meinen Webcrawler so ändern, dass alle Links, einschließlich der Anzeigen, gelöscht werden? Der entsprechende Code kann unten gefunden werden.Wie implementiere ich einen Web-Crawler, der Werbeblöcke streift?

Klasse Crawler (object):

def __init__(self, root, depth, locked=True): 
    self.root = root 
    self.depth = depth 
    self.locked = locked 
    self.host = urlparse.urlparse(root)[1] 
    self.urls = [] 
    self.links = 0 
    self.followed = 0 


def crawl(self): 
    #print " in crawl" 
    page = Fetcher(self.root) 
    q = Queue() 
    #print "made fetcher" 
    try: 
     page.fetch() 
     if page.urls == []: 
      print "Error: could not fetch urls for %s" % (self.root) 
      return 
      #raise KeyboardInterrupt 
     else: 
      target = open("output.txt", 'w') 
      for url in page.urls: 
       q.put(url) 
       target.write((url+'\n').encode('utf-8')) 
      followed = [self.root] 
      target.close() 

    except Exception as e: 
     print('Error: could not fetch urls') 
     raise KeyboardInterrupt 
     ''' 
    q = Queue() 
    target = open("output.txt", 'w') 
    for url in page.urls: 
     q.put(url) f 
     target.write((url+'\n').encode('utf-8')) 
    followed = [self.root] 
    target.close() 
    #print followed 
    ''' 

    n = 0 

    while True: 
     try: 
      url = q.get() 
     except QueueEmpty: 
      break 

     n += 1 

     if url not in followed: 
      try: 
       host = urlparse.urlparse(url)[1] 

       if self.locked and re.match(".*%s" % self.host, host): 
        followed.append(url) 
        #print url 
        self.followed += 1 
        page = Fetcher(url) 
        page.fetch() 
        for i, url in enumerate(page): 
         if url not in self.urls: 
          self.links += 1 
          q.put(url) 
          self.urls.append(url) 
          with open("data.out", 'w') as f: 
           f.write(url) 
        if n > self.depth and self.depth > 0: 
         break 
      except Exception, e: 
       print "ERROR: Can't process url '%s' (%s)" % (url, e) 
       print format_exc() 

Klasse-Abrufs (object):

def __init__(self, url): 
    self.url = url 
    self.urls = [] 

def __getitem__(self, x): 
    return self.urls[x] 

def _addHeaders(self, request): 
    request.add_header("User-Agent", AGENT) 

def open(self): 
    url = self.url 
    try: 
     request = urllib2.Request(url) 
     handle = urllib2.build_opener() 
    except IOError: 
     return None 
    return (request, handle) 

def fetch(self): 
    request, handle = self.open() 
    self._addHeaders(request) 
    if handle: 
     try: 
      content = unicode(handle.open(request).read(), "utf-8", 
        errors="replace") 
      soup = BeautifulSoup(content) 
      tags = soup('a') 
     except urllib2.HTTPError, error: 
      if error.code == 404: 
       print >> sys.stderr, "ERROR: %s -> %s" % (error, error.url) 
      else: 
       print >> sys.stderr, "ERROR: %s" % error 
      tags = [] 
     except urllib2.URLError, error: 
      print >> sys.stderr, "ERROR: %s" % error 
      tags = [] 
     for tag in tags: 
      href = tag.get("href") 
      if href is not None: 
       url = urlparse.urljoin(self.url, escape(href)) 
       if url not in self: 
        self.urls.append(url) 

def getLinks(url): 
    page = Fetcher(url) 
    page.fetch() 
    for i, url in enumerate(page): 
     print "%d. %s" % (i, url) 

Statische Methoden:

def main(): 
    depth =2 
    file_in = [] 
    reload(sys) 
    sys.setdefaultencoding('utf-8') 
    filename = "stuff.txt" 
    text = open(filename) 
    for line in text: 
     file_in.append(line.rstrip()) 


    for i in file_in: 
     print "Crawling %s (Max Depth: %d)" % (i, depth) 
     crawler = Crawler(i, depth) 
     crawler.crawl() 
     print "\n".join(crawler.urls) 
+0

Sie haben [scrapy] getaggt, aber Sie verwenden es nicht ... –

+0

Fragen, die Debugging-Hilfe suchen (** "Warum funktioniert dieser Code nicht?" **) müssen das gewünschte Verhalten * ein spezifisches Problem enthalten Fehler * und * der kürzeste Code erforderlich *, um es ** in der Frage selbst zu reproduzieren **. Fragen ohne ** eine klare Problemstellung ** sind für andere Leser nicht nützlich. Siehe: [Erstellen eines minimalen, vollständigen und überprüfbaren Beispiels] (http://stackoverflow.com/help/mcve). – MattDMo

Antwort

0

viel Werbung über Asynchronous JavaScript geliefert wird ausgeführt, auf der Seite. Wenn Sie nur die ursprüngliche Ausgabe des Servers scrapen, können Sie diese anderen Links nicht erhalten. Eine Methode wäre, einen kopflosen Browser wie PhantomJS zu verwenden, um den HTML-Code in eine Datei zu rendern und dann das Skript dazu zu verwenden. Es gibt noch andere Möglichkeiten.

Verwandte Themen