妹子图爬虫第三弹

妹子图爬虫第三弹

前面两篇的教程教大家写了一个基础的爬虫程序,但是有问题啊,每次开始时都要重新下载,很难受。所以我们要解决这个问题,关键点在于要把我们爬过的页面记录下来,避免重复。在这里,原文作者使用 MongoDB (一个基于分布式文件存储的非关系型数据库) 来存储数据的,我也是不怎么明白什么是 非关系型数据库…不过这里有教程,大家可以看看。

首先是 MongoDB 的安装。例如把它安在 C 盘下 D:\software\MongoDB\Server ,之后需要创建两个目录:

D:\software\MongoDB\mongod.log(文件) 存储日志

D:\software\MongoDB\db 存储数据

然后以管理员身份打开命令行窗口,执行以下命令

"D:\software\MongoDB\Server\3.4\bin\mongod.exe" --config "D:\software\MongoDB\Server\3.4\mongod.cfg" --install

如图安装成功

用命令 net start MongoDB 来启动服务。

对了,还需要安装 MongoDB 的 python 模块 pip install PyMongo

现在我们在上一篇博文完成的代码中导入模块:

from pymongo import MongoClient

代码改造第一步,在类 mzitu 里添加一个函数:

1
2
3
4
5
6
7
def __init__(self):
client = MongoClient() ##与MongDB建立连接(这是默认连接本地MongDB数据库)
db = client['meinvxiezhenji'] ## 选择一个数据库
self.meizitu_collection = db['meizitu'] ##在meizixiezhenji这个数据库中,选择一个集合
self.title = '' ##用来保存页面主题
self.url = '' ##用来保存页面地址
self.img_urls = [] ##初始化一个 列表 用来保存图片地址

之后要改一下 all_url 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def all_url(self, url):
html = down.get(url, 3)
all_a = BeautifulSoup(html.text, 'lxml').find('div', class_='all').find_all('a')
for a in all_a:
title = a.get_text()
self.title = title ##将主题保存到self.title中
print(u'开始保存:', title)
path = str(title).replace("?", '_')
self.mkdir(path)
os.chdir("D:\mzitu\\"+path)
href = a['href']
self.url = href ##将页面地址保存到self.url中
if self.meizitu_collection.find_one({'主题页面': href}): ##判断这个主题是否已经在数据库中、不在就运行else下的内容,在则忽略。
print(u'这个页面已经爬取过了')
else:
self.html(href)

接着改 html 函数:

1
2
3
4
5
6
7
8
def html(self, href):
html = down.get(href, 3)
max_span = BeautifulSoup(html.text, 'lxml').find_all('span')[10].get_text()
page_num = 0 ##这个当作计数器用 (用来判断图片是否下载完毕)
for page in range(1, int(max_span) + 1):
page_num = page_num + 1 ##每for循环一次就+1 (当page_num等于max_span的时候,就证明我们的在下载最后一张图片了)
page_url = href + '/' + str(page)
self.img(page_url, max_span, page_num) ##把上面我们我们需要的两个变量,传递给下一个函数。

改 img 函数…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def img(self, page_url, max_span, page_num): ##添加上面传递的参数
img_html = down.get(page_url, 3)
img_url = BeautifulSoup(img_html.text, 'lxml').find('div', class_='main-image').find('img')['src']
self.img_urls.append(img_url) ##每一次 for page in range(1, int(max_span) + 1)获取到的图片地址都会添加到 img_urls这个初始化的列表
if int(max_span) == page_num: ##我们传递下来的两个参数用上了 当max_span和Page_num相等时,就是最后一张图片了,最后一次下载图片并保存到数据库中。
self.save(img_url)
post = { ##这是构造一个字典,里面有啥都是中文,很好理解吧!
'标题': self.title,
'主题页面': self.url,
'图片地址': self.img_urls,
'获取时间': datetime.datetime.now()
}
self.meizitu_collection.save(post) ##将post中的内容写入数据库。
print(u'插入数据库成功')
else: ##max_span 不等于 page_num执行这下面
self.save(img_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
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
from bs4 import BeautifulSoup
import os
from Download import down ##导入模块变了一下
from pymongo import MongoClient
import datetime

class mzitu():

def __init__(self):
client = MongoClient() ##与MongDB建立连接(这是默认连接本地MongDB数据库)
db = client['meinvxiezhenji'] ## 选择一个数据库
self.meizitu_collection = db['meizitu'] ##在meizixiezhenji这个数据库中,选择一个集合
self.title = '' ##用来保存页面主题
self.url = '' ##用来保存页面地址
self.img_urls = [] ##初始化一个 列表 用来保存图片地址

def all_url(self, url):
html = down.get(url, 3)
all_a = BeautifulSoup(html.text, 'lxml').find('div', class_='all').find_all('a')
for a in all_a:
title = a.get_text()
self.title = title ##将主题保存到self.title中
print(u'开始保存:', title)
path = str(title).replace("?", '_')
self.mkdir(path)
os.chdir("D:\mzitu\\"+path)
href = a['href']
self.url = href ##将页面地址保存到self.url中
if self.meizitu_collection.find_one({'主题页面': href}): ##判断这个主题是否已经在数据库中、不在就运行else下的内容,在则忽略。
print(u'这个页面已经爬取过了')
else:
self.html(href)

def html(self, href):
html = down.get(href, 3)
max_span = BeautifulSoup(html.text, 'lxml').find_all('span')[10].get_text()
page_num = 0 ##这个当作计数器用 (用来判断图片是否下载完毕)
for page in range(1, int(max_span) + 1):
page_num = page_num + 1 ##每for循环一次就+1 (当page_num等于max_span的时候,就证明我们的在下载最后一张图片了)
page_url = href + '/' + str(page)
self.img(page_url, max_span, page_num) ##把上面我们我们需要的两个变量,传递给下一个函数。

def img(self, page_url, max_span, page_num): ##添加上面传递的参数
img_html = down.get(page_url, 3)
img_url = BeautifulSoup(img_html.text, 'lxml').find('div', class_='main-image').find('img')['src']
self.img_urls.append(img_url) ##每一次 for page in range(1, int(max_span) + 1)获取到的图片地址都会添加到 img_urls这个初始化的列表
if int(max_span) == page_num: ##我们传递下来的两个参数用上了 当max_span和Page_num相等时,就是最后一张图片了,最后一次下载图片并保存到数据库中。
self.save(img_url)
post = { ##这是构造一个字典,里面有啥都是中文,很好理解吧!
'标题': self.title,
'主题页面': self.url,
'图片地址': self.img_urls,
'获取时间': datetime.datetime.now()
}
self.meizitu_collection.save(post) ##将post中的内容写入数据库。
print(u'插入数据库成功')
else: ##max_span 不等于 page_num执行这下面
self.save(img_url)


def save(self, img_url):
name = img_url[-9:-4]
print(u'开始保存:', img_url)
img = down.get(img_url, 3)
f = open(name + '.jpg', 'ab')
f.write(img.content)
f.close()

def mkdir(self, path):
path = path.strip()
isExists = os.path.exists(os.path.join("D:\mzitu", path))
if not isExists:
print(u'建了一个名字叫做', path, u'的文件夹!')
os.makedirs(os.path.join("D:\mzitu", path))
return True
else:
print(u'名字叫做', path, u'的文件夹已经存在了!')
return False


Mzitu = mzitu() ##实例化
Mzitu.all_url('http://www.mzitu.com/all') ##给函数all_url传入参数 你可以当作启动爬虫(就是入口)

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×

keyboard_arrow_up 回到顶端