#encoding:utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
from sgmllib import SGMLParser
import re
import urllib
class URLLister(SGMLParser):
def start_a(self, attrs):
url = [v for k, v in attrs if k=='href']
if url : urll = url[0]
else : return
if urll :
if urll in globalList : return
if isSou(urll) :
if sechDir(imgList , urll) > 0 :
print 'Fetcher page at ' + ' img alredy saved ... ignore . Queue size : '+str(Queue.__len__())
imgList.append(urll)
return
else :
savImg(urll)
imgList.append(urll)
globalList.append(urll)
print 'Fetcher page at ' + urll + ' save img complete as . Queue size : '+str(Queue.__len__())
else :
if sechDir(fetList , urll) > 0 :
imgList.append(urll)
return
else :
imgList.append(urll)
enQ(urll)
print 'Fetcher page at ' + urll + ' a new url , append in Queue . Queue size : '+str(Queue.__len__())
def unknown_starttag(self , tag , attrs) :
return
fetList = [] # list of url listener fetched . 这是非资源url的历史列表,存在于此表中的url将不会再被爬取
imgList = [] # list of url saved pictures #这是资源url的历史列表,存在于此表中的资源不会再被下载
rgxStr = r'(http://www.bizhijidi.com/)*/wallpapers/[0-9]*/[0-9]*/[^x00-xff]*-900x1600.jpg' #这是需要下载资源的正则表达式,正则#表达式是啥我就不说了,不知道的自己去面壁。。
regrgStr = r'^(http://www.bizhijidi.com/)' #这是全局的网址正则匹配式
staURL = r'http://www.bizhijidi.com/' #这是起始的url
imgPath = r'/home/zhangjilun/bizhijidi/' #存放图片的本地路径
Queue = ['http://www.bizhijidi.com/'] #这是url队列,起始时只有起始url在里面
fileName = [] #filename全局列表。。。暂时木有用。。。留着备用
globalList = [] #全局url列表,用于第一次筛选url
#这是动态生成图片文件名的函数,就是取的url里的文件名
def changeName(url) :
if url :
s=url.split('/')
return s[-1]
#保存图片的函数,很简单的fileIO
def savImg(url) :
if url :
url = 'http://www.bizhijidi.com' + url
imgData = urllib2.urlopen(url).read()
imgName = changeName(url)
print imgName
p = imgPath + imgName
print 'File Path : '+p
output = open(p,'wb+')
print 'Saving img ... '
output.write(imgData)
output.close()
return 1
else :
return 0
#判断连接url是否符合站类url正则式,否则为站外连接,会被ignore掉
def inRange(url) :
if url :
#print 'cheak url is inrange : '
#print regrgStr
#print url
m = re.match(regrgStr , url)
if m : return 1
else : return 0
return 0
#判断url是否是一个资源图片url,同样用正则式实现
def isSou(url) :
if url :
#print 'cheak url is in source : '
#print url
m = re.match(rgxStr , url)
if m : return 1
else : return 0
return 0
#检查列表,如果列表中存在了该url,那么url会被ignore掉
def sechDir(List , url) :
if List : return -1
if url :
if List.__len__() == 0 :
List.append(url)
else :
if url in List : return 1
else : return 0
#入队列函数
def enQ(url) :
Queue.insert(0 , url)
return 1
#出队列函数
def deQ() :
url = Queue.pop()
print 'Pop url : ' + url
return url
#判断队列是否为空
def cheakQ() :
if Queue.__len__() != 0 : return 1
else : return 0
#最后有一个主方法:
def readPage(url):
sock=urllib.urlopen(url)
listener = URLLister()
listener.feed(sock.read())
sock.close()
listener.close()
return
#每弹出一个url,就调用这个主方法。
#就像这样:
while cheakQ() != 0 :
#print 'Reading page ... Queue len : ' + str(Queue.__len__())
readPage(deQ())
print 'Fetcher complete ...'
python实现图片爬虫,布布扣,bubuko.com
python实现图片爬虫