我目前正在研究蜘蛛;但是我需要能够多次调用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个链接,如何才能创建所有链接?
我怎样才能从链接中获取子网站,以便蜘蛛可以关注它们?
答案 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。