在列表中列出

ZCJ*_*ZCJ 2 python list

第二行的目的是什么?我们不是必须传入一个列表作为我们的seed参数吗?我认为你可以在我们拥有tocrawl变量的所有区域中使用种子,而不是在列表中有一个列表.

def crawl_web(seed):
    tocrawl = [seed]
    crawled = []
    while tocrawl:
        page = tocrawl.pop()
        if page not in crawled:
            union(tocrawl, get_all_links(get_page(page)))
            crawled.append(page)
    return crawled
Run Code Online (Sandbox Code Playgroud)

编辑:完整的脚本 - http://codepad.org/qxuzVkof

phi*_*hag 6

seed 不是列表,而是单个项目,很可能是要抓取的第一个页面的URL.

虽然可以更改函数的设计以允许多个种子URL,但这会使函数的签名复杂化- 几乎每个调用者都只想从一个URL进行爬网.使用函数修改调用者的变量也是不好的风格; 如果函数将采用参数tocrawl,则必须记录(并让每个调用者都知道):

  • tocrawl代表所有作为初始起点的网址
  • tocrawl必须是list(或兼容的类型); 一个普通的迭代并不能支持pop.它还必须符合union预期的属性.这是严重的不和谐.
  • 如果函数退出,则参数列表将为空.这意味着几乎所有调用者都希望传递列表的副本.
  • 如果函数以异常退出,tocrawl则将包含尚未爬网的URL快照.

由于最后两点本质上意味着输入参数被破坏,更好的设计是使参数成为任意可迭代,然后构造一个列表.这样,调用者就不必担心所有这些愚蠢的约定.

还有一件事:union您应该考虑set在两个实例中使用a ,而不是编写自己的实现并使用列表存储所有已爬网站,如下所示:

def crawl_web(seed):
    tocrawl = set([seed])
    crawled = set()
    while tocrawl:
        page = tocrawl.pop()
        if page not in crawled:
            tocrawl.update(get_all_links(get_page(page)))
            crawled.add(page)
    return crawled
Run Code Online (Sandbox Code Playgroud)