0%

小白爬虫第三弹之去重去重

QQ图片20161022193315 好了!开头要说点啥,我想你们已经知道了! QQ图片20161021224219 没错!我又来装逼了·· 前面两篇博文,不知道大家消化得怎么了。不知道各位有没注意到,前面两篇博文完成的工作,只能保证下载;你电脑不能关机,不能断网,总之不能出意外!否则啊!!! !!!!你就得重头开始啊!!!! 20160124759183737 今天,我们来想想办法让它不重头下载;我们来记录我们已经下载过的地址!ヾ(@⌒ ー ⌒@)ノ这样就可以实现不重新下载啦! 本来刚开始我是准备用本地 txt 来记录的,不过仔细一想用本地 txt 逼格不够啊!要不用 MySQL 吧!然后我自己就用了 MySQL。 QQ图片20161102215153 然而你以为我会在这教程里面用 MySQL 嘛!哈哈哈!我们来用 MongoDB!!这数据库最近很火啊!逼格直线提升啊!哈哈哈!点我去官网下载 安装 mongoDB: 123 在 C 盘建一个用来存储数据的文件夹 MongoDB; 创建以下两个目录: C:\data\log\mongod.log 存储日志 C:\data\db 存储数据 在 C:\MongoDB 文件夹下面创建一个 mongod.cfg 的配置文件写入以下配置: 一定要取消隐藏后缀名,不然更改不会生效!

1
2
3
4
5
systemLog:
destination: file
path: C:\data\log\mongod.log
storage:
dbPath: C:\data\db

在管理员权限的 cmd 中执行以下命令将 mongoDB 安装成服务:

1
"C:\mongodb\bin\mongod.exe" --config "C:\mongodb\mongod.cfg" --install

安装服务 上面两张图片是 GIF 点击是可以看到过程的哦!!!ヾ(=゚・゚=)ノ喵 ♪ 服务器安装完了,CMD 启动一下: 验证是否安装成功 搞定! 好啦!数据库装完了,我们来接着上一篇博文的内容继续啦! 保险起见建议大家还是看一下 MongoDB 的基础(只需要知道那些命令是做了啥,这样就好啦!) 首先我们我们这一次需要一个模块 PyMongo;这是 Python 用来操作 MongoDB 的模块,不要担心使用起来很简单的!

1
pip install PyMongo

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

1
from pymongo import MongoClient

第一步: 在 class 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 = [] ##初始化一个 列表 用来保存图片地址

好啦!第一步搞定, 第二步: 我们更改一下 def 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)

第三步: 我们来改一下 def 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) ##把上面我们我们需要的两个变量,传递给下一个函数。

第四步: 我们来改一下 def 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)

self.meizitu_collection.save(post) 这个是怎么来的我要说一下,可能有点迷糊: def init(self): 函数中: client = MongoClient() db = client[‘meinvxiezhenji’] self.meizitu_collection = db[‘meizitu’] 所以意思就是:在 meizixiezhenji 这个数据库中的 meizitu 这个集合保存 post 这个字典里面的数据哦!这么解释懂了吧?ヾ(@⌒ ー ⌒@)ノ QQ图片20161021223818 好了、一个可以实现去重的爬虫就实现了!φ(゜ ▽ ゜*)♪ 是不是好简单 哈哈哈 顺带还存储了一堆信息(才不会告诉你们这才是我需要的呢) 好了 完整的代码贴上来了! PS:需要先说一下 MongDB 是不需要先建数据库和集合的,会自动判断 存在则直接写入数据,不存在 则先创建需要的数据库和集合,再写入数据(是不是超爽?哈哈哈)

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
83
84
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传入参数 你可以当作启动爬虫(就是入口)