作者开发的爬取妹子图片Python项目,值得你收藏拥有

news/2024/7/19 11:29:30 标签: python, beautifulsoup, 爬虫, 网络爬虫, 个人开发

最好的学习方法在于实践,学习编程语言Python,也是同样的道理。本文讲解自己开发的一个项目,实现爬取妹子图片,所用的Python知识点以及模块,可以关注参考作者公众号的Python语言合集。

—、前情介绍

1.1 涉及模块

本项目的实现涉及模块有,

requestsBeautifulSoupostimeloggingre

1.2 网站信息以及项目代码地址

爬取图片所在网站地址:https://www.xrmn03.cc/

项目完整代码所在gitee:https://gitee.com/shawn_chen_rtz/meizi_pic.git

欢迎关注,STAR

1.3 执行效果

执行后生成的文件夹效果,

图片

日志信息,可以查看当前执行下载情况,

图片

二、单张图片保存方法

2.1 在线图片保存方法

python">def save_pic(direct, pic_src, pic_no):
    """保存单个图片,根据目录direct,图片地址pic_src,图片保存名称pic_no."""
    pic_url = "https://www.xrmn03.cc" + pic_src.attrs['src']
    if not os.path.exists(direct + "/" + str(pic_no) + ".jpg"):
        for _ in range(20):
            try:
                pic_binary = requests.get(url=pic_url).content
                with open(direct + "/" + str(pic_no) + ".jpg", "wb") as img:
                    img.write(pic_binary)
            except Exception:
                time.sleep(60)
            else:
                break

以上是保存图片方法save_pic(),它接收三个参数direct, pic_src, pic_no,分别表示欲存储的目录、图片链接和图片编号(用作命名图片文件)。

首先拼接成图片完整链接pic_url,再判断图片是否已存在路径中,如果不存在,开始执行保存操作,通过requests模块发出请求,读取图片数据pic_binary = requests.get(url=pic_url).content,通过文件写操作写入到本地路径下,文件操作可以参考个人公众号(欢迎关注)文章Python:文本文件的读、写处理。在请求过程中,可能基于网络等原因,报错异常,所以放在了一个循环体中,并在循环体中用try...except...else异常处理机制handle错误。如果出错,会等待60秒后继续请求,一共20次重试机会,也就是循环次数range(20);如果成功,则会直接跳出后续循环请求。异常处理机制可以参考个人公众号文章Python:异常处理。

三、获取整套图方法

3.1 获取整套图方法

思路:观察该网站的图集展示逻辑,一套图集中是以多个分页组成的。

图片

图片

图片

可以观察到每个分页链接的组成是有一定规律的,根据规律获取单套图集每个分页的链接后,循环请求分页链接,在循环体中增加从每个分页的响应结果中爬取出包含图片的超链接功能,结合第二章的save_pic()方法,把图片保存到本地。

代码实现,

python">def get_full_album(album_address, title):
    """获取整个图集的图片,根据图集地址album_address和图集名称title"""
    if not os.path.exists(title):
        os.mkdir(title)
    # 图集中的第i张图片
    i = 1
    for album_page in range(100):
        album_page_url = (
                "https://www.xrmn03.cc/" + album_address) if album_page == 0 else "https://www.xrmn03.cc/" + album_address.rstrip(
            ".html") + "_" + str(album_page) + ".html"
        for _ in range(20):
            try:
                pics_page = requests.get(url=album_page_url)
            except requests.exceptions.ChunkedEncodingError as err:
                logger.error(f"occur {err}")
                time.sleep(60)
            except requests.exceptions.ConnectionError as err:
                logger.error(f"{current_time()} occur {err}")
                time.sleep(60)
            else:
                pics_page.encoding = "utf-8"
                pics_soup = BeautifulSoup(pics_page.text, 'html.parser')
                # 如果页面中不存在class_="content",图集下载完成。
                if not pics_soup.findAll(class_="content"):
                    logger.info("{album} all downloaded".format(album=title))
                    return
                pics = pics_soup.findAll(class_="content")[0]
                pics = pics.findAll('img')
                if pics:
                    for pic in pics:
                        save_pic(title, pic, i)
                        i = i + 1
                break

可以看到获取整套图方法get_full_album(album_address, title)接收两个参数,分别表示图集地址album_address和图集名称title。

首先,判断路径下是否已存在与图集名称同名的文件夹,如果不存在,通过os.mkdir(title)进行创建。循环遍历for album_page in range(100),album_page表示图集中的分页,获取每个分页的超链接​​​​​​​,

python">album_page_url = (
                "https://www.xrmn03.cc/" + album_address) if album_page == 0 else "https://www.xrmn03.cc/" + album_address.rstrip(
            ".html") + "_" + str(album_page) + ".html"

用的格式是if分支语句的缩略写法。比如举个例子,大于0的数字是正数,相反则是非正数。正常写法是,​​​​​​​

python">if a > 0:
    print("Positive NO.")
else:
    print("Not Positive NO.")

​​​​​​​​​​​​​​简写格式则是,两种形式是等效的。

print("Positive NO.") if a > 0 else print("Not Positive NO.")

循环请求分页地址,循环体内请求分页链接,根据访问详情结果,用BeautifulSoup提取出所有的图片链接,循环图片数据,调用save_pic(title, pic, i)方法,下载至本地保存。

当然同保存图片方法一样,也使用了异常处理机制,增强代码运行的健壮性与稳定性。如果发生异常错误时,用for循环的方式增加重试/重新请求的机制。

四、遍历获取图集地址/名称

4.1 遍历图集

代码实现,​​​​​​​

python">for page in range(1, 24):
    url = "https://www.xrmn03.cc/XiuRen/" if page == 1 else "https://www.xrmn03.cc/XiuRen/index" + str(page) + ".html"
    resp = requests.get(url=url)
    resp.encoding = "utf-8"
    html = resp.text
    soup = BeautifulSoup(html, 'html.parser')
    albums = soup.findAll(class_="i_list list_n2")
    logger.info("Page No.{page} starting...".format(page=page))
    # 当前分页的第album_no图集
    album_no = 1
    for album in albums:
        album_url = album.find('a').attrs['href']
        album_title = album.find('a').attrs['title']
        logger.info("No.{no} album starting...".format(no=album_no))
        # 以下条件语句判断图集文件中的照片数量和图集名称中提取出的数量是否一致。如果一致则跳过该次循环。
        if os.path.exists(album_title):
            num_from_title = re.search(r'\d{2,3}P', album_title).group().strip("P")
            # print(num_from_title)
            if len(os.listdir("./" + album_title)) == int(num_from_title):
                logger.info("No.{no} album all already have saved before!".format(no=album_no))
                album_left = 30 - album_no
                if album_left > 0:
                    logger.info(f"当前分页{page},还剩{album_left}套待下载")
                album_no += 1
                continue
        get_full_album(album_url, album_title)
        logger.info("No.{no} album all saved!".format(no=album_no))
        album_left = 30 - album_no
        if album_left > 0:
            logger.info(f"当前分页{page},还剩{album_left}套图集待下载")
        album_no += 1
    logger.info("Page No.{page} completed".format(page=page))

遍历图集分页,获取图集的链接,

图片

根据图集分页链接组成规律,获取链接,for循环for page in range(1, 24)控制下载的页数范围,当前是下载1到23页的所有图集的图集信息。

获取所有albums,循环albums,处理得到图集链接album_url,图集名称album_title,如果已存在同名文件夹,并且文件夹中的图片数量与图集名称中的图片数量一致时,略过该图集,并写入对应日志信息。如果不存在同名文件夹,或者文件夹中的图片数量与文件夹名称中的数量不一致,则调用第三章中的get_full_album(album_url, album_title)方法。

ok,到这里结束了,有任何问题请留言或关注作者公众号,与我交流~


可以关注作者微信公众号,追踪更多有价值的内容!


http://www.niftyadmin.cn/n/5458467.html

相关文章

HCIP的学习(6)

OSPF—开放式最短路径优先协议 动态路由的评判标准 1、占用资源 2、收敛速度 3、选路动态路由分类: IGP---内部网关协议DV型---距离矢量型---RIPLS型---链路状态型---OSPFEGP---外部网关协议OSPF---无类别的路由协议(携带真实掩码)组播224.0…

Towhee

文章目录 关于 Towhee✨ 项目特点🎓 快速入门流水线预定义流水线自定义流水线 🚀 核心概念 关于 Towhee Towhee 是一个开源的 embedding 框架,包含丰富的数据处理算法与神经网络模型。通过 Towhee,能够轻松地处理非结构化数据&am…

Day26 手撕各种集合底层源码(一)

Day26 手撕各种集合底层源码(一) 一、手撕ArrayList底层源码 1、概念: ArrayList的底层实现是基于数组的动态扩容结构。 2、思路: 1.研究继承关系 2.研究属性 3.理解创建集合的过程 – 构造方法的底层原理 4.研究添加元素的过程…

【详细讲解如果Tomcat启动后闪退的解决方法】

🌈个人主页:程序员不想敲代码啊🌈 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家🏆 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提…

语言模型:解密AI语言理解之道

在这个信息爆炸的时代,我们每天都在与海量的文本数据打交道。如何从这些文本中提炼出有价值的信息,成为了科技界的一大挑战。而语言模型,正是解决这一挑战的关键技术之一。今天,就让我们一起走进语言模型的神秘世界,探索其原理、实战与评估的奥秘。 一、原理篇:语言模型…

git配置SSH 密钥

git配置SSH 密钥 1.window配置ssh1.安装ssh2.安装 Git(安装教程参见安装Git)并保证版本大于 1.9![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e59f4e16b83c45649f1d9d7bd6bf92c0.png)3.SSH 尽量保持最新,6.5之前的版本由于使用…

14 Games101 - 笔记 - 光线追踪(利用包围盒技术加速光线追踪(KD-Tree and BVH)

14 光线追踪(利用包围盒技术加速光线追踪(KD-Tree and BVH) 在上一节中,我们介绍了whited-style光线追踪的原理,以及实现细节。相比与光栅化中所使用的的Blinn-Phong模型,光线追踪显著了提升了图像质量&am…

[树莓派5] [解决]关于键盘打不出@#或者@与双引号互换的问题[亲测的正确的做法][并且还是us键盘的情况下]

问题:shift引号的键,敲出符号;shift2,敲出双引号,刚好反了,而且美元符号变成了英镑符号。查看了 /etc/default/keyboard,确认XKBLAYOUT"us",问题还是存在。 解决&#xf…