用Python来做一个可以爬取网络上衣着暴(裸)露的妹子(帅哥)图片的小爬虫

首先声明:本程序的宗旨是为了提升大家对写代码的热情,有时候,并不是因为不得已的工作而去敲代码,而是为了享受写代码的乐趣,或者是程序跑起来那一刻的成就感。所以,不管结果如何,请大家用科学的眼光来看待这个小程序。话不多说,赶紧进入正题。

同时,因为我也是一个毕业不到一年的程序小菜,学python不到3个月的时间,所以很多东西可能会不是很正确,或者不是用的最好的方案来实现,所以请大家多多包涵,如果您有更好的办法,或者算法,欢迎留言指正。


1.程序运行的环境

这里我选择了使用最新版的python3.5,然后用到的库除了python自带的,还有pillow这个图片处理库(安装pillow的方法很简单,可以使用pip install pillow,如果不知道pip怎么安装,请自行百度,py3应该是自带pip的)。

2.功能第一步 判断图片是否为暴露的

作为一个初学者,我们的能力有限,不可能从更加宏大的算法角度来入手,判断图片是否是为人,是男是女,是黑种人还是白种人,是穿了衣服还是没穿衣服。这些问题,是国内研究生,甚至博士生们所研究的课题。那也不代表我们这些普通程序员就不能涉足这样的领域。所以说,我们这里所用到的算法,当然不是高大上的,但是是我们每个人都能理解的。

那我们怎么判断一张图片是否是暴露的呢?

我们可以思考下暴露图片中的相同的属性,看看这样的图片,都会有一些什么样的共性。

(图片都取自网络)

图1:

image

图2:

image

大家都知道,图一的穿着比图二暴露多了(图一根本就没有穿衣服好不好)。我们肉眼识别是很简单,但是机器如何去识别这两张图片之间的差别呢。

没错,我们这里用最简单的一个办法。这个办法就是判断,人的肉色,在整张图片中所占的比例。

我们首先用强大的pillow库来分析每一张照片,这里我采用了YCbCr模式(这种模式会将所有像素的颜色分为三个参数,Y代表亮度,Cb代表蓝度,Cr代表红度),这样我们只有确定肉色在YCbCr中的一个取值范围,便能做出整张照片的一个像素统计。然后我们取一个比例,如果肉色像素占了整张照片像素的30%,那么我们就可以假定,这是一张穿着很暴露(露肉很多)的一张照片了。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# encoding: utf-8
import sys
from PIL import Image

def IsPictureNaked(imgsrc):
img = Image.open(imgsrc).convert('YCbCr')
w, h = img.size
data = img.getdata()
cnt = 0
count = 0
for i, ycbcr in enumerate(data):
y, cb, cr = ycbcr
count+=1
if 86 <= cb <= 117 and 140 <= cr <= 168:
cnt += 1
if(cnt > w * h * 0.3):
return True
else:
return False

ok,通过这段代码,我们就能对照片进行一个基本的判定了。

3.功能第二步 做一个小爬虫

先看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import re
import urllib.request
import Naked
import os

# 输入开始地址
# url = "http://www.27270.com/ent/meinvtupian/"
print('请输入您要爬的网址')
url = input()
print('请输入网址的编码格式')
codeStyle = input()
htmlGetCode = 0


def getHtml(url):
page = urllib.request.urlopen(url)
global htmlGetCode
htmlGetCode = page.getcode()
html = page.read().decode(codeStyle)
return html


def getImg(html):
reg = r'src="(.+?\.jpg)"'
imgre = re.compile(reg)

imglist = imgre.findall(html)
x = 0
for imgurl in imglist:
print(imgurl)
urllib.request.urlretrieve(+imgurl, '%s.jpg' % x)
picsname = str(x) + '.jpg'
result = Naked.IsPictureNaked(picsname)
if (result == True):
x = x + 1
continue
else:
os.remove(picsname)
x = x + 1
print('删除了不符合要求%d' % (x))
continue


html = getHtml(url)
if (htmlGetCode == 200):
getImg(html)
else:
print(htmlGetCode)
print('网址未找到')

其实准确的来说,这并不是一个爬虫。因为它只提供了爬虫的一部分功能,那就是解析网址,并获取一些相关的信息,但是如果你想要拓展这段代码,实现爬虫的功能也是不难的,只需要实现url的获取,存储的功能就可以了(关于python小爬虫的开发我们以后再来研究)。

看下这段代码实现的功能吧,首先 import re ,re这个库是用来实现正则表达式匹配的功能的,urllib当然就是解析网页不可缺少的库了, os库主要是因为我们要对下载下来的照片,进行必要的筛选,留下符合我们的naked算法的,不符合的我们将其删除。

这里对各个方法进行简单的讲解,getHtml——首先对用urllib.request.urlopen(url)解析url,然后赋值给page,这时候的page还不是那种我们能直观阅读的html代码,于是我们还需要像html = page.read().decode(codeStyle)这样的方法来解析下,使用codeStyle中的编码格式来对page进行相应的解析。最后变量html就是我们所需要的网页代码了。

有了网页的源代码,我们就赶紧对这源代码进行我们的照片提取工作吧。reg = r’src=”(.+?.jpg)”‘,提取工作的第一步当然是写一个正则表达式,用这个正则表达式来匹配我们所需要的代码,这里我们匹配的字符串是凡事带有以’src’开头,然后以’.jpg’来结尾的字符串。然后只要我们把这段正则表达式在网页源代码中进行遍历一次,拿到了所有的符合要求的字符串就可以了。(这里的图片url就是imgurl)。

然后我们用urllib.request.urlretrieve()这个方法来进行图片的下载,使用合适的命名规则将爬到的图片做好保存。接下来的最后一步也是最重要的一步了,就是拿出我们之前写好的暴露图片的检测方法,对下载下来的图片进行一次检查,然后删除不需要的图片,这样留下来的图片就是符合我们暴露图片筛选规则的啦。

当然,由于图片鉴定算法的限制,我们肯定不能抓取到100%符合我们预期的图片,但是还是能筛选掉一部分图片,实战效果怎么样,可以自己去检测,不过要提醒的是,很多大头的照片也是符合我们的筛选算法的……所以结果你懂得……

结语:这只是一个简单的单页小程序,还并不能构成一个强大的网络爬虫,我们还需要写一个url的管理程序来管理所爬取到的url,后面的功能我会在以后的时间去逐步完善,感谢阅读。