网络爬虫不会打开页面中的所有链接

Web crawler does not open all links in a page

我正在尝试使用 beautifulsoup 和 urllib 构建网络爬虫。爬虫正在运行,但它不会打开站点中的所有页面。它打开第一个 link 并转到那个 link,打开那个页面的第一个 link 等等。 这是我的代码:

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')

如果 count 达到 100,将不再打开 link。因此,我认为您应该在离开 for 循环后将 count 减一。如果这样做,count 将类似于当前的 link 深度(100 将是最大 link 深度)。

如果变量 count 应该指的是打开的 link 的数量,那么您可能想用另一种方式控制 link 深度。

您看到此行为的原因是代码递归调用您的函数。一旦代码找到有效的 link,函数 f 就会再次被调用,从而阻止 for 循环的其余部分从 运行 直到 returns.

你做的是深度优先搜索,但是互联网非常深。您想改用广度优先搜索。

修改代码以实现此目的的最简单方法可能是拥有要遵循的 link 的全局列表。让 for 循环将所有抓取的 links 附加到此列表的末尾,然后在 for 循环之外,删除列表的第一个元素并跟随 link.

您可能需要针对最大计数稍微更改您的逻辑。