0

我目前正在研究蜘蛛;但我需要能够多次调用 Spider() 函数来跟踪链接,这是我的代码:

import httplib, sys, re

def spider(target, link):
        try:
        conn = httplib.HTTPConnection(target)
        conn.request("GET", "/")
        r2 = conn.getresponse()
        data = r2.read().split('\n')
        for x in data[:]:
            if link in x:
                a=''.join(re.findall("href=([^ >]+)",x))
                a=a.translate(None, '''"'"''')
                if a:
                    return a
    except:
        exit(0)

print spider("www.yahoo.com", "http://www.yahoo.com")

但我只从输出中获得 1 个链接,我怎样才能使所有链接都成为这个链接?

还有如何从链接中获取子站点,以便蜘蛛可以跟踪它们?

4

2 回答 2

2

这可能更接近您正在寻找的内容

import httplib, sys, re

def spider(link, depth=0):
    if(depth > 2): return []

    try:
        conn = httplib.HTTPConnection(link)
        conn.request("GET", "/")
        r2 = conn.getresponse()
        data = r2.read().split('\n')
        links = []
        for x in data[:]:
            if link in x:
                a=''.join(re.findall("href=([^ >]+)",x))
                a=a.translate(None, '"' + "'")
                if a:
                    links.append(a)

        # Recurse for each link
        for link in links:
            links += spider(link, (depth + 1))

        return links

    except:
        exit(1)

print spider("http://www.yahoo.com")

它未经测试,但基础知识就在那里。抓取所有链接,然后递归抓取它们。该函数在每次调用时返回页面上的链接列表。并且当一个页面被递归爬取时,递归调用返回的那些链接被添加到这个列表中。该代码还具有最大递归深度,因此您不会永远走下去。

它缺少一些明显的疏忽,例如循环检测。

一些旁注,有更好的方法来做这些事情。

例如,urllib2可以比使用 httplib 更容易地为您获取网页。

BeautifulSoup从网页中提取链接比您的 regex + translate kluge 更好。

于 2013-06-18T00:28:01.433 回答
0

按照门把手的提示,如果您只是将 更改return ayield a,您的函数将成为生成器。不是调用它并返回结果,而是调用它并返回一个迭代器——你可以循环的东西。

因此,将您的if块更改为:

if link in x:
    a=''.join(re.findall("href=([^ >]+)",x))
    a=a.translate(None, '''"'"''')
    if a:
        yield a

然后将您的print声明更改为:

for a in spider("www.yahoo.com", "http://www.yahoo.com"):
    print a

你完成了。

但是,我猜你并不是真的想join升级findall; 你想分别循环遍历每个“找到”的东西。你如何解决这个问题?很简单,只需围绕re.findall,yield循环一次:

if link in x:
    for a in re.findall("href=([^ >]+)",x)):
        a=a.translate(None, '''"'"''')
        if a:
            yield a

有关生成器和迭代器如何工作的更详细说明,请参阅此演示文稿

于 2013-06-18T00:40:54.373 回答