• Python爬虫02——贴吧图片爬虫V2.0


    Python小爬虫——贴吧图片爬虫V2.0

    贴吧图片爬虫进阶:在上次的第一个小爬虫过后,用了几次发现每爬一个帖子,都要自己手动输入帖子链接,WTF这程序简直反人类!不行了不行了得改进改进


      思路:  

    • 贴吧的链接可以从每个贴吧首页爬取
    • 再从爬取到的贴吧链接中一个个去下载图片
    • 图片得按帖子放置好,不然就太乱了

    在这期间研究了下Xpath:

    Xpath是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。

    简单点来说就是能让你的爬虫通过标签的id、class、name等属性可以获取到标签的属性或内容的一门语言,就不用去写讨厌的正则表达式了(刚开始用正则人都要炸了)

    Xpath的学习视频呢,在这里--->Go

    当然其实用re也能实现,废话也不多说了,开始正题了


      帖子链接的爬取:  

    我们的目标当然是:壁纸吧、萌妹子、爆照吧等等等等

    作为一个绅士还是以壁纸吧来做示范吧:http://tieba.baidu.com/f?kw=%E5%A3%81%E7%BA%B8&ie=utf-8

    打开壁纸吧

     通过右键检查、或是查看源码找到每个帖子的标签

    帖子的标签在这里

    <a href="/p/4686986115" title="【壁纸】江湖多风雨,天下已入秋" target="_blank" class="j_th_tit ">【壁纸】江湖多风雨,天下已入秋</a>

    应该就是href后面的哪个 "/p/4686986115" 了

    点进去果然,就是在前面多了串 http://tieba.baidu.com 

    OK!那把链接爬取出来就相当容易了:

    from lxml import etree
    
    def getArticleLinks(url):
        html = requests.get(url)
        Selector = etree.HTML(html.text)
        # 通过Xpath 获取每个帖子的url后缀
        url_list = Selector.xpath('//div[@class="threadlist_lz clearfix"]/div/a/@href')
        # 在每个后缀前加上百度贴吧的url前缀
        for i in range(len(url_list)):
            url_list[i] = 'http://tieba.baidu.com' + url_list[i]
        return url_list

      图片按文件夹下载:  

     先是一个帖子的图片下载:

    def get_img(url):
        html = requests.get(url)
        # 这里用Xpath或者之前的re拿到img_url_list
        Selector = etree.HTML(html.text)
        img_url_list = Selector.xpath('//*[@class="BDE_Image"]/@src')
        pic_name = 0
        # 下载图片
        for each in img_url_list:
            urllib.urlretrieve(each, 'pic_%s.jpg' % pic_name)
            pic_name += 1

    其实这样已经差不多了,再来个循环每个帖子链接来一次 get_img 就可以获取到所有的图片,但是这样的话:

    1. 那么多帖子的图片在一起很乱
    2. 下一个帖子的图片会把上一个帖子图片覆盖(因为都是pic_00.jpg开始的,且都在一个文件夹内)

    我的想法是建一个downloads文件夹,然后在里面按帖子分文件夹存放下载下来的图片

    # 该目录下创建一个downloads文件夹存放下载图片
        if not os.path.exists('downloads'):
            os.mkdir('downloads')

    当然是没有的时候建立,有的话就可以不用了

    然后按帖子分文件夹

    # 这里把帖子url的后缀作为文件夹名,因为不能有'/'所以把它替换成了''
    img_dir = 'downloads/' + url_list[i][23:].replace("/", '')
            if not os.path.exists(img_dir):
                os.mkdir(img_dir)

    然后就可以下载了:

    def download_img(url_list):
        if not os.path.exists('downloads'):
            os.mkdir('downloads')
        for each in url_list:
            img_dir = 'downloads/' + each[23:].replace("/", '')
            if not os.path.exists(img_dir):
                os.mkdir(img_dir)
            get_img(each)

    然而并没有一个个图片按帖子放好,文件夹是建好了。

    经过研究发现,应该在 get_img 之前应该先把当前目录改为要放的文件夹目录下

     os.chdir(path) 可以用来改变python当前所在的文件夹

    然后在下载完一个帖子后得移回当前目录,最后的代码就是:

    def download_img(url_list):
        # 该目录下创建一个downloads文件夹存放下载图片
        if not os.path.exists('downloads'):
            os.mkdir('downloads')
        root_path = os.getcwd()
        for each in url_list:
            img_dir = 'downloads/' + each[23:].replace("/", '')
            if not os.path.exists(img_dir):
                os.mkdir(img_dir)
            os.chdir(img_dir)
            get_img(each)
            os.chdir(root_path)

    啪啪啪啪啪[完美]


      交互:  

     老样子和之前的第一个小爬虫一样,添加一些交互。

    不过我发现,一个贴吧第一页的帖子也贼多,然后由于爬虫暂时还是单线程的

    所以若是要将整个第一页爬完,也是要花挺多时间,就稍微修改了下,加了一个帖子个数的输入

    最终的代码:

    # coding:utf-8
    import requests
    import os
    import urllib
    import re
    from lxml import etree
    
    # 通过url获取每个帖子链接
    def getArticleLinks(url):
        html = requests.get(url)
        Selector = etree.HTML(html.text)
        # 通过Xpath 获取每个帖子的url后缀
        url_list = Selector.xpath('//div[@class="threadlist_lz clearfix"]/div/a/@href')
        # 在每个后缀前加上百度贴吧的url前缀
        for i in range(len(url_list)):
            url_list[i] = 'http://tieba.baidu.com' + url_list[i]
        return url_list
    
    # 通过所给帖子链接,下载帖子中所有图片
    def get_img(url):
        html = requests.get(url)
        Selector = etree.HTML(html.text)
        img_url_list = Selector.xpath('//*[@class="BDE_Image"]/@src')
        pic_name = 0
        for each in img_url_list:
            urllib.urlretrieve(each, 'pic_%s.jpg' % pic_name)
            pic_name += 1
    
    # 为每个帖子创建独立文件夹,并下载图片
    def download_img(url_list,page):
        # 该目录下创建一个downloads文件夹存放下载图片
        if not os.path.exists('downloads'):
            os.mkdir('downloads')
        root_path = os.getcwd()
        for i in range(page):
            img_dir = 'downloads/' + url_list[i][23:].replace("/", '')
            if not os.path.exists(img_dir):
                os.mkdir(img_dir)
            os.chdir(img_dir)
            get_img(url_list[i])
            os.chdir(root_path)
    
    if __name__ == '__main__':
        print u'-----贴吧图片爬取装置2.0-----'
        print u'请输入贴吧地址:',
        targetUrl = raw_input('')
        if not targetUrl:
            print u'---没有地址输入正在使用默认地址(baidu壁纸吧)---'
            targetUrl = 'http://tieba.baidu.com/f?kw=%E5%A3%81%E7%BA%B8&ie=utf-8'
    
        page = ''
        while True:
            print u'请输入你要下载的帖子数:',
            page = raw_input('')
            if re.findall(r'^[0-9]*[1-9][0-9]*$',page):
                page = int(page)
                break
        print u'----------正在下载图片---------'
        ArticleLinks = getArticleLinks(targetUrl)
        download_img(ArticleLinks,page)
        print u'-----------下载成功-----------'
        raw_input('Press Enter to exit')

    界面:

    不要脸的说自我感觉良好23333

    结构是这样滴

     内容(爬取的内容怎么和我不一样?我不管23333)

     # 结尾的啪啪啪啪啪

  • 相关阅读:
    找回感觉的练习
    第四次博客作业-结对项目
    zookeeper启动脚本
    docker自己制作centos7-jdk1.8-tomcat8
    Docker运行springboot的项目
    从list中模糊查询字符串
    Java实现文件下载
    hadoop的HA集群搭建
    oauth2 feign 报401的错误
    SpringBoot mybatis 自定义分页插件 注解版
  • 原文地址:https://www.cnblogs.com/Axi8/p/5773269.html
Copyright © 2020-2023  润新知