該指令碼的主要是從網上抓取資源存入本地檔案
指令碼中Retriever 類的責任是從 Web 下載頁面,解析每個文檔中的連結並在必要的時候把它們加入
“to-do”隊列。我們為每個從網上下載的頁面都建立一個 Retriever 類的執行個體。Retriever 中的方
法展現了它的功能:構造器(__init__())、filename()、download()、和parseAndGetLinks()。
filename()方法使用給定的URL找出安全、有效相關檔案名稱並儲存在本地。大體上說,它會
去掉 URL 的“http://”首碼,使用剩餘的部分作為檔案名稱,並建立必要的檔案夾路徑。那些沒有
檔案名稱首碼的URL則會被賦予一個預設的檔案名稱“index.htm”。(可以在調用filename()時重新指定
這個名字。)
構造器執行個體化了一個 Retriever 對象,並把 URL 和通過 filename()獲得的相應檔案名稱都作為本
地屬性儲存起來。
'''<br />Created on 2010-12-21<br />@author: Administrator<br />'''<br />from sys import argv<br />from os import makedirs,unlink,sep<br />from os.path import dirname,exists,isdir,splitext<br />from string import replace,find,lower<br />from htmllib import HTMLParser<br />from urllib import urlretrieve<br />from urlparse import urlparse,urljoin<br />from formatter import DumbWriter,AbstractFormatter<br />from cStringIO import StringIO<br />#import model you need<br />class Retriever(object):<br /> def __init__(self,url):<br /> self.url=url<br /> self.file=self.filename(url)<br /> def filename(self,url,deffile='index.htm'):<br /> parsedurl=urlparse(url,'http:',0)<br /> path=parsedurl[1]+parsedurl[2]<br /> ext=splitext(path)<br /> if ext[1]=='':<br /> if path[-1]=='/':<br /> path+=deffile<br /> else:<br /> path+='/'+deffile<br /> ldir=dirname(path)<br /> if sep!='/':<br /> ldir=replace(ldir,'/',sep)<br /> if not isdir(ldir):<br /> if exists(ldir):unlink(ldir)<br /> makedirs(ldir)<br /> return path</p><p> def download(self):<br /> try:<br /> retval=urlretrieve(self.url,self.file)<br /> except IOError:<br /> retval=('***ERROR :invalid URL "%s"' %self.url,)<br /> return retval </p><p> def parseAndGetLinks(self):<br /> print 'file:%s' % self.file<br /> self.parser=HTMLParser(AbstractFormatter(DumbWriter(StringIO)))<br /> self.parser.feed(open(self.file).read())<br /> self.parser.close()<br /> return self.parser.anchorlist<br />class Crawler(object):<br /> count=0</p><p> def __init__(self,url):<br /> self.q=[url]<br /> self.seen=[]<br /> self.dom=urlparse(url)[1]</p><p> def getPage(self,url):<br /> r=Retriever(url)<br /> retval=r.download()<br /> if retval[0]=='*':<br /> print retval,'...skipping parse'<br /> return<br /> Crawler.count+=1<br /> print '/n(',Crawler.count,')'<br /> print 'URL:',url<br /> print 'FILE:',retval[0]<br /> self.seen.append(url)</p><p> links=r.parseAndGetLinks()<br /> for eachLink in links:<br /> if eachLink[:4]!='http' and find(eachLink,'://')==-1:<br /> print "*",eachLink<br /> if eachLink not in self.seen:<br /> if find(eachLink,self.dom)==-1:<br /> print '...discarded,not in domain'<br /> else:<br /> if eachLink not in self.q:<br /> self.q.append(eachLink)<br /> print '...new ,added to Q'<br /> else:<br /> print '...discarded,already in Q'<br /> else:<br /> print '...discarded,already processed'</p><p> def go(self):<br /> while self.q:<br /> url=self.q.pop()<br /> self.getPage(url)</p><p>def main():<br /> if len(argv)>1:<br /> url=argv[1]<br /> else:<br /> try:<br /> url=raw_input('Enter starting URL:')<br /> except(KeyboardInterrupt,EOFError):<br /> url=''<br /> if not url:return<br /> robot=Crawler(url)<br /> robot.go()<br />if __name__=='__main__':<br /> main()</p><p>
運行: