IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    aiyo发表于 2016-11-05 17:22:09
    love 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的配置文件写入以下配置:

    一定要取消隐藏后缀名,不然更改不会生效!

    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这个字典里面的数据哦!这么解释懂了吧?ヾ(@⌒ー⌒@)ノ

    QQ图片20161021223818

    好了、一个可以实现去重的爬虫就实现了!φ(゜▽゜*)♪是不是好简单 哈哈哈

    顺带还存储了一堆信息(才不会告诉你们这才是我需要的呢)

    好了 完整的代码贴上来了!

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

     

    转载请注明:静觅 » 小白爬虫第三弹之去重去重



沪ICP备19023445号-2号
友情链接