如何在python中返回多个值

时间:2013-06-18 00:18:55

标签: python web-crawler httplib

我目前正在研究蜘蛛;但是我需要能够多次调用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个链接,如何才能创建所有链接?

我怎样才能从链接中获取子网站,以便蜘蛛可以关注它们?

2 个答案:

答案 0 :(得分: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从网页中提取的链接比正则表达式+翻译kluge更好。

答案 1 :(得分:0)

根据门把手的提示,如果您只是将return a更改为yield a,则您的功能将变为generator。您可以调用它并返回迭代器,而不是调用它并返回结果,而是可以循环。

因此,请将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

有关生成器和迭代器如何工作的更详细说明,请参阅this presentation