2016-11-02 2 views
-1

Ich versuche, einen Web-Crawler mit beautifulsoup und urllib zu erstellen. Der Crawler funktioniert, aber er öffnet nicht alle Seiten einer Site. Es öffnet den ersten Link und geht zu diesem Link, öffnet den ersten Link dieser Seite und so weiter. Hier ist mein Code:Web-Crawler öffnet nicht alle Links auf einer Seite

from bs4 import BeautifulSoup 
from urllib.request import urlopen 
from urllib.parse import urljoin 
import json, sys 

sys.setrecursionlimit(10000) 

url = input('enter url ') 
d = {} 
d_2 = {} 
l = [] 
url_base = url 
count = 0 

def f(url): 
    global count 
    global url_base 
    if count <= 100: 
     print("count: " + str(count)) 
     print('now looking into: '+url+'\n') 
     count += 1 
     l.append(url) 
     html = urlopen(url).read() 
     soup = BeautifulSoup(html, "html.parser") 
     d[count] = soup 
     tags = soup('a') 

     for tag in tags: 
      meow = tag.get('href',None) 

      if (urljoin(url, meow) in l): 
       print("Skipping this one: " + urljoin(url,meow)) 
      elif "mailto" in urljoin(url,meow): 
       print("Skipping this one with a mailer")  
      elif meow == None: 
       print("skipping 'None'") 

      elif meow.startswith('http') == False: 
       f(urljoin(url, meow))  
      else: 
       f(meow) 
    else: 
     return 


f(url) 
print('\n\n\n\n\n') 
print('Scrapping Completed') 
print('\n\n\n\n\n') 
+0

Ich denke, das wäre hier angemessener: http://codereview.stackexchange.com/ – Nicarus

+0

Wenn Sie keine Regel verwenden, um es zu steuern, dann wird es nie aufhören. – furas

Antwort

0

Der Grund, aus dem dieses Verhalten auftritt, liegt daran, dass der Code die Funktion rekursiv aufruft. Sobald der Code eine gültige Verbindung findet, wird die Funktion f erneut aufgerufen, wodurch verhindert wird, dass der Rest der for-Schleife ausgeführt wird, bis sie zurückkehrt.

Was Sie tun, ist eine Tiefensuche zuerst, aber das Internet ist sehr tief. Sie möchten stattdessen eine breite erste Suche durchführen.

Wahrscheinlich ist die einfachste Möglichkeit, Ihren Code zu ändern, dies zu tun, um eine globale Liste von Links folgen zu haben. Lassen Sie die for-Schleife alle abgeschabten Links an das Ende dieser Liste anhängen und entfernen Sie dann außerhalb der for-Schleife das erste Element der Liste und folgen Sie diesem Link.

Möglicherweise müssen Sie Ihre Logik leicht für Ihre maximale Anzahl ändern.

+0

Vielen Dank Mann. Das hat perfekt funktioniert. Aber kann ich eine Tiefenzahl angeben? Wie, ich möchte fünf Stufen des Atems zuerst suchen? –

+0

Sicher. Fügen Sie der Funktion, die die Tiefenebene verfolgt, einen Parameter hinzu: def f (url, depth) - Rufen Sie sie dann, wenn Sie sie rekursiv aufrufen, mit (depth + 1) auf. Vergessen Sie nicht, am Anfang einen Scheck hinzuzufügen, der sofort zurückkehrt, wenn er über Ihrer gewünschten Tiefe liegt. – yonomitt

0

Wenn count 100 erreicht, werden keine weiteren Verbindungen geöffnet werden. Deshalb denke ich, du solltest count um eins nach Verlassen der for-Schleife verringern. Wenn Sie dies tun, wäre count etwas wie die aktuelle Linktiefe (und 100 wäre die maximale Linktiefe).

Wenn die Variable count sich auf die Anzahl der geöffneten Verbindungen beziehen sollte, möchten Sie die Verbindungstiefe möglicherweise auf andere Weise steuern.

Verwandte Themen