如何爬取豆瓣妹子上的照片

  豆瓣妹子是一个收集豆瓣美女的第三方网站,主要收集来自豆瓣羞涩组,害羞组,长腿组等兴趣爱好小组的用户自行上传的照片,大家在这边可以收藏自己喜欢的豆瓣美女。那么我们怎么很快的下载这些妹子的照片到自己的电脑上来收藏呢?好吧,我承认我写了个可以很快下载这些照片的爬虫程序,有多快?试过你就知道。
  虽然这个想法是我看来的,但是代码都是我自己写的。好的话不多说,下面开始啦。


  其首页的布局如下图。有这么多栏目,我们就以白色区域的栏目来讲解吧。
       贴图1
  首先主页的网址是:http://www.dbmeizi.com,“所有”是:http://www.dbmeizi.com/category/10,“性感”是:http://www.dbmeizi.com/category/1,等等就不一个个说了,自己打开看下,应该都是主页后面加上一定的代码。那么我们就可以写出一定的代码来取得正确的url:

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
info = u'''
-------------------------
1.所有
2.性感
3.有沟
4.美腿
5.小清新
6.文艺
7.美臀
请输入数字选择要下载的类别:
--------------------------
'''
print(info)
num = raw_input() #获取下载选项
choices = {
'1':r'10',
'2':r'1',
'3':r'2',
'4':r'3',
'5':r'11',
'6':r'12',
'7':r'14'
}
choice = choices[num]
base_url = r'http://www.dbmeizi.com/category/'
choice_url = base_url + choice #要下载的页面的首页url



  我们再到开每个栏目翻页看看,就会发现同一类别不同页数之间的差别。第一页是:http://www.dbmeizi.com/category/1?p=0,第二页是:http://www.dbmeizi.com/category/1?p=1,细心的同学应该已经发现规律了。好的,那我们就开始写代码吧:

1
2
3
4
5
6
7
8
9
print(u'请输入起始页数:')
startpage = input() - 1
print(u'请输入结束页数:')
endpage = input() - 1
page_index = r'?p='
url_pages = [] #储存所有要下载的url
#拼接url的各个部分
for index in range(startpage, endpage + 1):
url_pages.append(choice_url + page_index + str(index))

  其中的input() == eval(raw_input()),在这里我们可以直接使我们取得的变量为整形。我们分了几个部分把每个页面的url给拼接了出来,注意最后拼接的时候必须全都是字符串才行。


  在下载之前我们还有2个问题要解决:

  • 第一:下载的图片放哪里?
  • 第二:图片的链接是什么?

  第一个问题的解决方法显然就是要创建或选择一个文件夹,那我们就写个简单的代码吧:

1
2
3
4
5
6
7
8
9
import os #引入os模块
print(u'请输入要保存图片的绝对路径:')
dir_path = raw_input() #保存路径名
print(u'请输入要保存图片的文件夹名称:')
dir_title = raw_input() #保存文件夹名
new_path = os.path.join(dir_path, dir_title) #拼接出最终的路径
if not os.path.isdir(new_path): #如果不存在就创建文件夹
os.makedirs(new_path)
print(u'将把图片保存在:%s' % new_path)

  第二个问题是要得到下载的链接。写过爬虫的肯定知道这一步是必须用正则表达式的,没错,那我们就一步步来看。上面我们已经取得了要下载的各个页面的url,打开一个,在一张图片上右击“审查元素”,我们可以看到下面图片显示的信息:
贴图2
  我们看到阴影处就是图片的html代码,学过html的都知道图片的链接就在src后面双引号里,没学过看到.jpg也明白了吧。好了有了这一串代码我们就要开始解析并匹配了,之后取到各个链接之后我们直接下载保存在我们建好的文件夹里就行了。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import urllib2,re,urllib #引入需要的模块
#开始下载该页面所有的图片
j = startpage #用来给图片编号
for page in url_pages: #循环每个要下载的页面
myUrl = page #取出一个url
content = urllib2.urlopen(myUrl).read().decode('utf-8') #获取url的html代码
pattern = re.compile(r'<img.*?class=".*?_min".*?src="(.*?)".*?alt=.*?>'\
,re.S) #正则表达式对象
allurl = re.findall(pattern, content) #找到并返回所有符合对象的值,即图片链接
i = 0 #编号用
for item in allurl:
location = r'%s\%s_%s.jpg' % (new_path, j, i) #图片存储路径
urllib.urlretrieve(item, location) #下载图片到指定位置
i += 1
j += 1

  这里需要引入urllibrullibre模块,分别用于打开链接和正则匹配。urllib2.urlopen(myUrl)打开url作为一个对象,然后.read()是读取内容,.decode('utf-8')是解码为unicoude(自身编码是utf-8)。
。完成这段我们就搞定了所有的代码了。


最后整理一下代码:

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# -*- coding: utf-8 -*-
import os
import urllib2,urllib
import re
info = u'''
-------------------------
1.所有
2.性感
3.有沟
4.美腿
5.小清新
6.文艺
7.美臀
请输入数字选择要下载的类别:
--------------------------
'''
print(info)
num = raw_input() #获取下载选项
choices = {
'1':r'10',
'2':r'1',
'3':r'2',
'4':r'3',
'5':r'11',
'6':r'12',
'7':r'14'
}
choice = choices[num]
base_url = r'http://www.dbmeizi.com/category/'
choice_url = base_url + choice #要下载的页面的首页url
print(u'请输入起始页数:')
startpage = input() - 1
print(u'请输入结束页数:')
endpage = input() - 1
page_index = r'?p='
url_pages = [] #储存所有要下载的url
#拼接url的各个部分
for index in range(startpage, endpage + 1):
url_pages.append(choice_url + page_index + str(index))
print(u'请输入要保存图片的绝对路径:')
dir_path = raw_input() #保存路径名
print(u'请输入要保存图片的文件夹名称:')
dir_title = raw_input() #保存文件夹名
new_path = os.path.join(dir_path, dir_title) #拼接出最终的路径
if not os.path.isdir(new_path): #如果不存在就创建文件夹
os.makedirs(new_path)
print(u'将把图片保存在:%s' % new_path)
j = startpage #用来给图片编号
for page in url_pages: #循环每个要下载的页面
myUrl = page #取出一个url
content = urllib2.urlopen(myUrl).read().decode('utf-8') #获取url的html代码
pattern = re.compile(r'<img.*?class=".*?_min".*?src="(.*?)".*?alt=.*?>'\
,re.S) #正则表达式对象
allurl = re.findall(pattern, content) #找到并返回所有符合对象的值,即图片链接
i = 0 #编号用
for item in allurl:
location = r'%s\%s_%s.jpg' % (new_path, j, i) #图片存储路径
urllib.urlretrieve(item, location) #下载图片到指定位置
i += 1
j += 1

  # -*- coding: utf-8 -*-是告诉编译器本文件的编码,在IDLE中必须加上才能运行。整理好了是不是整齐多了,赶紧去试试下载的快感吧!
  本程序还是有很多的可改进之处的,比如:页数输入的正确性检测、文件夹创建过程的正确性检测、下载过程的多线程化等等还有好多,以后会改进的,敬请期待!

版权:本文采用以下协议进行授权,自由转载 - 非商用 - 非衍生 - 保持署名 | Creative Commons BY-NC-ND 3.0,转载请注明作者及出处。