【问题标题】:Trying to create a python web crawler尝试创建一个 python 网络爬虫
【发布时间】:2013-11-05 20:40:25
【问题描述】:

我正在尝试使用 python 实现网络爬虫。 这是我目前所拥有的:

import urllib2

seed=raw_input('Enter a url : ')

def getAllNewLinksOnPage(page,prevLinks):

response = urllib2.urlopen(page)
html = response.read()

links,pos,allFound=[],0,False
while not allFound:
    aTag=html.find("<a href=",pos)
    if aTag>-1:
        href=html.find('"',aTag+1)
        endHref=html.find('"',href+1)
        url=html[href+1:endHref]
        if url[:7]=="http://":
            if url[-1]=="/":
                url=url[:-1]
            if not url in links and not url in prevLinks:
                links.append(url)     
                print url
        closeTag=html.find("</a>",aTag)
        pos=closeTag+1
    else:
        allFound=True   
return links

toCrawl=[seed]
crawled=[]
while toCrawl:
url=toCrawl.pop()
crawled.append(url)
newLinks=getAllNewLinksOnPage(url,crawled)
toCrawl=list(set(toCrawl)|set(newLinks))

print crawled   

我想知道如何实施深度搜索并对结果进行排序。

【问题讨论】:

  • 你见过scrapy吗? scrapy.org
  • 如果你想自己动手学习udacity example
  • 请修正缩进,并包含所有缺失的代码(如有必要)以使其成为可运行的示例,以便我们知道您缺少什么。
  • 使用 HTML 解析器(如标准库中内置的解析器)或 BeautifulSouplxml 等第三方库,解析 HTML 和查找链接要容易得多。但看起来您的getAllNewLinksOnPage 不是您遇到问题的部分,对吧?
  • 我认为你应该首先使用xpath和lxml

标签: python python-2.7 web-crawler


【解决方案1】:

到目前为止,您实施的是一种随机顺序搜索,因为您保留了要抓取的链接的 set。 (您实际上保留了 list,但反复将其转换为 set,这会打乱您的任何顺序。)

要将其转换为深度优先搜索,通常的解决方案是递归进行。然后,您不需要任何外部存储链接即可进行爬网。您确实仍然需要跟踪到目前为止已抓取的链接——既是为了避免重复,又是因为您希望在最后对链接进行排序(这需要对某些内容进行排序),但仅此而已。所以:

def crawl(seed):
    crawled = set()
    def crawl_recursively(link):
        if link in crawled:
            return
        newLinks = getAllLinksOnPage(link)
        crawled.add(seed)
        for link in newLinks:
            crawl_recursively(link)
    crawl_recursively(seed)
    return sorted(crawled)

如果您不想使用递归,另一种方法是使用显式链接堆栈进行爬网。但是你不能继续重新组织那个堆栈,或者它不再是一个堆栈。同样,一组单独的已抓取链接将解决避免重复查找的问题。

def crawl(seed):
    crawled = set()
    to_crawl = [seed]
    while to_crawl:
        link = to_crawl.pop()
        if link in crawled:
            continue
        crawled.add(link)
        newLinks = getAllLinksOnPage(link)
        to_crawl.extend(newLinks)
    return sorted(crawled)

将堆栈变成一个队列(只需将一行更改为to_crawl.pop(0))使这是一个广度优先搜索。

如果您担心 to_crawl 变得太大,因为它充满了重复,您可以随时删除它们。由于您想要深度优先,因此您想要去掉那些堆积起来供以后使用的东西,而不是新的。最简单的方法可能是使用OrderedSet(例如,从collections 文档链接的recipe):

    to_crawl = OrderedSet()
    # …
        new_link_set = OrderedSet(newLinks)
        to_crawl -= new_link_set
        to_crawl |= new_link_set - crawled

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-06
    • 2014-01-26
    • 2021-05-26
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 2013-10-15
    相关资源
    最近更新 更多