好了!开头要说点啥,我想你们已经知道了!
没错!我又来装逼了··
前面两篇博文,不知道大家消化得怎么了。不知道各位有没注意到,前面两篇博文完成的工作,只能保证下载;你电脑不能关机,不能断网,总之不能出意外!否则啊!!!
!!!!你就得重头开始啊!!!!
今天,我们来想想办法让它不重头下载;我们来记录我们已经下载过的地址!ヾ(@⌒ー⌒@)ノ这样就可以实现不重新下载啦!
本来刚开始我是准备用本地txt来记录的,不过仔细一想用本地txt逼格不够啊!要不用MySQL吧!然后我自己就用了MySQL。
然而你以为我会在这教程里面用MySQL嘛!哈哈哈!我们来用MongoDB!!这数据库最近很火啊!逼格直线提升啊!哈哈哈!点我去官网下载
安装mongoDB:
在C盘建一个用来存储数据的文件夹 MongoDB;
创建以下两个目录:
C:\data\log\mongod.log 存储日志
C:\data\db 存储数据
在C:\MongoDB文件夹下面创建一个mongod.cfg的配置文件写入以下配置:
一定要取消隐藏后缀名,不然更改不会生效!
systemLog: destination: file path: C:\data\log\mongod.log storage: dbPath: C:\data\db
在管理员权限的cmd 中执行以下命令将mongoDB安装成服务:
"C:\mongodb\bin\mongod.exe" --config "C:\mongodb\mongod.cfg" --install
上面两张图片是GIF点击是可以看到过程的哦!!!ヾ(=゚・゚=)ノ喵♪
服务器安装完了,CMD启动一下:
搞定!
好啦!数据库装完了,我们来接着上一篇博文的内容继续啦!
保险起见建议大家还是看一下MongoDB的基础(只需要知道那些命令是做了啥,这样就好啦!)
首先我们我们这一次需要一个模块 PyMongo;这是Python用来操作MongoDB的模块,不要担心使用起来很简单的!
pip install PyMongo
现在我们在上一篇博文完成的代码中导入模块:
from pymongo import MongoClient
第一步:
在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函数:
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这个函数:
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 这个函数:
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这个字典里面的数据哦!这么解释懂了吧?ヾ(@⌒ー⌒@)ノ
好了、一个可以实现去重的爬虫就实现了!φ(゜▽゜*)♪是不是好简单 哈哈哈
顺带还存储了一堆信息(才不会告诉你们这才是我需要的呢)
好了 完整的代码贴上来了!
PS:需要先说一下MongDB是不需要先建数据库和集合的,会自动判断 存在则直接写入数据,不存在 则先创建需要的数据库和集合,再写入数据(是不是超爽?哈哈哈)
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传入参数 你可以当作启动爬虫(就是入口)
转载请注明:静觅 » 小白爬虫第三弹之去重去重