首页 > 代码库 > 80行Python代码实现自动爬取色情网站图片

80行Python代码实现自动爬取色情网站图片

用Python爬取色情网站的图片,技术宅的小玩具。在这里我将会向你详细介绍用Python下载一个色情网站图片的全部步骤,你会从中看到Python的简洁以及技术宅的无聊。

首先你应该应该有一个色情网站的网址,当然我不会给你的,自己找!!!我会告诉你其中的规律:

http://www.*****.com/htm/piclist【1】/【2】.htm
一个色情网站的图片区中,URL不同的只有【1】【2】两处,通过观察你可以发现,【1】处表示图片种类(丝袜美腿、清纯唯美、****、and so on),【2】处表示当前分类的第N页目录,所以。首先我们可以构建一个表示图片列表目录URL地址:

baseurl = 'http://www.*****.com/htm/piclist%s/%s.htm'
urls = [baseurl % (x,y) for x in xrange(1,10) for y in xrange(1,10)]
这即是当前网站所有图片分类的所有前9页内容。

然后来分析每页目录的结构:

可以看出,每一条目录对应着一个<a>标签并被包含在一个<li>中,故以此可以构建一个分析HTML页面的解析器:

class ImgIdxPageParser(sgmllib.SGMLParser):
    ''' parse a image index page '''
    def __init__(self):
        sgmllib.SGMLParser.__init__(self)
        self.imgurlList = []
        self.tagList = []
        self.ontitle = False
    def unknown_starttag(self, tag, attrs):
        if tag == 'li':
            self.tagList.append('li')
        elif tag == 'a' and len(self.tagList):
            self.imgurlList.append(WEBSITE + attrs[0][1])
        elif tag == 'title':
            self.ontitle = True
    def unknown_endtag(self,tag):
        if tag == 'li':
            self.tagList.pop()
        elif tag == 'title':
            self.ontitle = False
    def handle_data(self, data):
        if self.ontitle:
            title = data.decode('utf-8').encode('gb2312').strip()
            self.title = title[:title.find('_')]
                        

由于使用到sgmllib.SGMLParser,我们应该先import sgmlib。在ImgIdxPageParser中,我们通过title保存当前页面所处的分类,用imgurlList保存每一条目录地址。关于sgmllib.SGMLParser的介绍,请点击这里。

对此,我们构建一个函数,返回指定目录下的分类名称以及目录列表:

def getPageUrlList(page):
    ''' get title and all the pages list of a picIndex page ''' 
    parser = ImgIdxPageParser()
    parser.feed(urllib2.urlopen(page).read())
    return parser.imgurlList, parser.title
这个函数返回page页面里的所有目录条目以及所处的分区(丝袜美腿、清纯唯美、****、and so on)。

接着我们打开其中一个图片页分析如下:


理所当然,图片链接被放置在<img>的‘src’中,对此,我们构建第二个解析器——用于解析图片页面的每个图片的地址:

class ImagePageParser(sgmllib.SGMLParser):
    ''' parse a image page's image urls '''
    def __init__(self):
        sgmllib.SGMLParser.__init__(self)
        self.imgurlList = []
    def unknown_starttag(self, tag, attrs):
        if tag == 'meta' and attrs[0][1] == 'description':
            self.title = attrs[1][1].decode('utf-8').encode('gb2312').strip()
        elif tag == 'img':
            for key, value in attrs:
                self.imgurlList.append(value) if key == 'src' else None 
在ImagePageParser中,我们通过title保存当前页面的标题,用imgurlList保存每一个图片的地址。同样我们需要构建一个函数来使用ImagePageParser,并返回所有的图片地址以及这些图片的标题:

def getImageUrlList(pageUrl):
    ''' get all image urls from a page '''
    parser = ImagePageParser()
    parser.feed(urllib2.urlopen(pageUrl).read())
    return parser.imgurlList, parser.title
getImageUrlList函数返回pageUrl页面里所有图片的地址以及这个页面的标题。

由于我们的得到的所有地址都是以列表形式展现出来,所以我们需要一个函数,一次性把一个列表中所有的图片下载下来:

def downloadImage(imgList, save=''):
    ''' download images of a list '''
    if not (os.path.exists('save') and os.path.isdir(save)):
        try:
            os.makedirs(save)
        except Exception,e:pass
    for x in imgList:
        try:
            filename = save + '\\' + x[x.rfind('/') + 1:]
            print filename
            urllib.urlretrieve(x, filename)
        except Exception, e:
            print 'exception catched:', e
在downloadImage函数中,我们接收一个图片地址列表和一个保存路径(非必须,如果没有则在当前目录下保存),函数开始时if是为了保证在传入的save路径不存在时,先创建一个文件夹。然后是遍历图片地址的列表,通过urllib.urlretrieve()函数来下载每一个图片。关于urllib的详细介绍,请点击这里。我们在for里面使用try-except的目的是,当下载一张图片发生错误时(网络断线、文件IO出错或者任何未知错误时),不会让整个程序崩溃掉。

当准备工作完成以后,我们就可以开始下载图片了,剩下的任务就是对刚才所有的积木进行拼装整合了:

if __name__ == '__main__':
    basepath = 'G:\\__temp\\'
    baseurl = 'http://www.*****.com/htm/piclist%s/%s.htm'
    urls = [baseurl % (x,y) for x in xrange(1,10) for y in xrange(1,10)]
    for url in urls:
        try:
            pagelist, outtitle = getPageUrlList(url)
            print outtitle, pagelist
            for page in pagelist:
                imglist, intitle = getImageUrlList(page)
                downloadImage(imglist, save= basepath + outtitle + '\\' + intitle)
        except Exception, e:
            print 'excepiton catched:' , e
这就完成了对程序的组合,到此就可以实现自动下载色情网站的图片了,而且由于对标题的处理,我们得到的将会是按照网站上保存结构同样的目录层级。

当然程序到这里还有很多需要处理的,比如为了提高效率我们需要多线程的加入,对图片下载可能的错误做完整的处理等等,对此,请记住一句话:自力更生,丰衣足食!


80行Python代码实现自动爬取色情网站图片