2016-11-02 1 views
-1

Я пытаюсь создать веб-искатель с помощью beautifulsoup и urllib. Искатель работает, но он не открывает все страницы сайта. Он открывает первую ссылку и переходит к этой ссылке, открывает первое соединение этой страницы и так далее. Вот мой код:Веб-искатель не открывает все ссылки на странице

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

Я думаю, что здесь было бы более уместно: http://codereview.stackexchange.com/ – Nicarus

+0

, если вы не используете какое-либо правило для его контроля, оно никогда не остановится. – furas

ответ

0

Причина, по которой вы видите это поведение, объясняется тем, что код рекурсивно вызывает вашу функцию. Как только код найдет допустимую ссылку, функция f снова вызывается, что предотвращает запуск остальной части цикла for до ее возвращения.

Что вы делаете, это поиск по глубине, но интернет очень глубокий. Вместо этого вы хотите выполнить поиск по ширине.

Возможно, самый простой способ изменить свой код, чтобы сделать это, - это иметь глобальный список ссылок. Пусть цикл for добавит все очищенные ссылки в конец этого списка, а затем за пределами цикла for, удалите первый элемент списка и следуйте этой ссылке.

Возможно, вам придется немного изменить свою логику для вашего максимального счета.

+0

Спасибо большое. Это сработало отлично. Но могу ли я указать количество глубин? например, я хочу сделать пять уровней первого поиска? –

+0

Конечно. Добавьте параметр к функции, которая отслеживает уровень глубины: def f (url, depth). Затем, когда вы рекурсивно вызываете его, назовите его (глубина + 1). Не забудьте добавить чек в начале, который немедленно возвращается, если он находится выше желаемой глубины. – yonomitt

0

Если count достигает 100, не будет открыто никаких дальнейших ссылок. Поэтому я думаю, что вы должны уменьшить count на один после выхода из цикла for. Если вы сделаете это, count будет чем-то вроде текущей глубины связи (и 100 будет максимальной глубиной канала).

Если переменная count должна ссылаться на количество открытых ссылок, вы можете захотеть контролировать глубину связи по-другому.