百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

手把手教你利用Python爬虫采集二次元美女壁纸

myzbx 2025-03-03 19:26 25 浏览

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:

https://blog.csdn.net/LOVEmy134611/article/details/118540051

前言

(又到了常见的无中生友环节了)我有一个朋友,最近沉迷二次元,想要与喜欢的二次元角色度过一生,就像11区与初音未来结婚的阿宅那样。于是作为为朋友两肋插刀的正义的化身,决定为其充满魔幻现实的人生再添加一抹亮色,让他深陷其中无法自拔,于是在二次元的宇宙里,帮他用Python获取了二次元女友(们)。

私信小编01即可获取大量Python学习资源

尽管二次元知识人类幻想出来的唯美世界,但其本质上还是我们心中模糊的对梦想生活的憧憬和对美好未来的期望,这卡哇伊的颜,爱了爱了,我给你讲。


程序说明

通过爬取知名二次元网站——触站,获取高清动漫图片,并将获取的webp格式的图片转化为更为常见的png格式图片。

二次元女友获取程序

使用requests库请求网页内容,使用BeautifulSoup4解析网页,最后使用PIL库将webp格式的图片转化为更为常见的png格式图片。

观察网页结构

首先选择想要获取的图片类型,这里已女孩子为例,当然大家也可以选择生活或者脚掌,甚至是男孩子

进入女孩子标签页面,观察页面链接,爬取多个页面,查看第2页链接为:

https://www.huashi6.com/tags/161?p=2

第3页链接为:

https://www.huashi6.com/tags/161?p=3

可以看出,不同页面网址仅改变了页面数字,因此可以构造如下模式,并使用循环,爬取所有页面:

url_pattern = "https://www.huashi6.com/tags/161?p={}"
for i in range(1, 20):
????url?=?url_pattern.format(i)

接下来,在爬取网页前,使用浏览器“开发者工具”,观察网页结构。首先尝试定位图片元素:


于是自然想到使用
find_all语法获取所有class=‘v-lazy-img v-lazy-image-loaded’的标签:

img_url?=?soup.find_all('img',?attr={'class':?'v-lazy-img?v-lazy-image-loaded'})

但是发现并未成功获取,于是经过进一步探索发现,其图片信息是在script元素中动态加载的:


需要注意的是,在请求页面时,可以在构造请求头时,添加
'Cookie'键值,但是没有此键值也能够运行。

headers = {
    'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0',
    # 根据自己的情况修改Cookie值
    #'Cookie':''
}
url_pattern = "https://www.huashi6.com/tags/161"
response?=?requests.get(url=url,?headers=headers)

页面解析

使用beautifulsoup解析页面,获取JS中所需数据:

results?=?soup.find_all('script')[1]

为了能够使用re解析获取内容,需要将内容转换为字符串:

image_dirty?=?str(results)

接下来构造正则表达式获取图片地址:

pattern?=?re.compile(item,?re.I|re.M)

然后查找所有的图片地址:

result_list?=?pattern.findall(image_dirty)

为了方便获取所需字段,构造解析函数

def analysis(item,results):
    pattern = re.compile(item, re.I|re.M)
    result_list = pattern.findall(results)
????return?result_list

打印获取的图片地址:

urls  = analysis(r'"path":"(.*?)"', image_dirty)
urls[0:1]

发现一堆奇怪的字符:

'images\\u002Fresource\\u002F2021\\u002F06\\u002F20\\u002F906h89635p0.jpg',

这是由于网页编码的原因造成的,由于一开始使用utf-8方式解码网页,并不能解码Unicode

response.encoding = 'utf-8'
response.raise_for_status()
soup?=?BeautifulSoup(response.text,?'html.parser')

因此虽然可以通过以下方式获取原始地址:

url = 'images\u002Fresource\u002F2021\u002F05\u002F22\u002F90h013034p0.jpg'
decodeunichars?=?url.encode('utf-8').decode('unicode-escape')

但是我们可以通过response.encoding = 'unicode-escape'进行更简单的解码,缺点是网页的许多中文字符会变成乱码,但是字不重要不是么?看图!

创建图片保存路径

为了下载图片,首先创建图片保存路径:

# 创建图片保存路径
if not os.path.exists(webp_file):
    os.makedirs(webp_file, exist_ok=True)
if not os.path.exists(png_file):
????os.makedirs(png_file,?exist_ok=True)

图片下载

当我们使用另存为选项时,发现格式为webp,但是上述获取的图片地址为jpgpng,如果直接存储为jpgpng格式,会导致格式错误。

因此需要重新构建webp格式的文件名:

name = img.split('/')[-1]
name = name.split('.')[0]
name_webp?=?name?+?'.webp'

由于获取的图片地址并不完整,需要添加网站主页来构建图片地址:

from urllib.request import urljoin
domain = 'https://img2.huashi6.com'
img_url?=?urljoin(domain,img)

接下来就是下载图片了:

r = requests.get(img_url,headers=headers)
if r.status_code == 200:
  with open(name_webp, 'wb') as f:
????f.write(r.content)

格式转换

最后,由于得到的图片是webp格式的,如果希望得到更加常见的png格式,需要使用PIL库进行转换:

image_wepb = Image.open(name_webp)
image_wepb.save(name_png)

爬取结果展示

完整程序

import time
import requests
from bs4 import BeautifulSoup
import os
import re
from urllib.request import urljoin
from PIL import Image


webp_file = 'girlfriends_webp'
png_file = 'girlfriends_png'


print(os.getcwd())


# 创建图片保存路径
if not os.path.exists(webp_file):
    os.makedirs(webp_file, exist_ok=True)
if not os.path.exists(png_file):
    os.makedirs(png_file, exist_ok=True)


headers = {
    'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0',
    #'Cookie':''
    'Connection': 'keep-alive'
}
url_pattern = "https://www.huashi6.com/tags/161?p={}"


domain = 'https://img2.huashi6.com'


# 图片地址获取函数
def analysis(item,results):
    pattern = re.compile(item, re.I|re.M)
    result_list = pattern.findall(results)
    return result_list
    
# 图片格式转换函数
def change_webp2png(name_webp, name_png, img_url):
    try:
        image_wepb = Image.open(name_webp)
        image_wepb.save(name_png)
    except:
        download_image(name_webp, name_png, img_url)


# 图片下载函数
def download_image(name_webp, name_png, img_url):
    if not os.path.exists(name_png):
        if os.path.exists(name_webp):
            os.remove(name_webp)
        print(img_url)
        r = requests.get(img_url,headers=headers)
        # print(r.content)
        time.sleep(5)
        if r.status_code == 200:
            with open(name_webp, 'wb') as f:
                f.write(r.content)
        change_webp2png(name_webp, name_png, img_url)


for i in range(1, 20):
    time.sleep(5)
    url = url_pattern.format(i)
    response = requests.get(url=url, headers=headers)
    # 解码
    # response.encoding = 'utf-8'
    response.encoding = 'unicode-escape'
    response.raise_for_status()
    soup = BeautifulSoup(response.text, 'html.parser')


    results = soup.find_all('script')


    image_dirty = str(results[1])


    urls  = analysis(r'"path":"(.*?)"', image_dirty)[:20]


    for img in urls:
        img_url = urljoin(domain,img)


        # 获取文件名
        name = img.split('/')[-1]
        name = name.split('.')[0]
        name_webp = name + '.webp'
        name_webp = os.path.join(webp_file, name_webp)
        name_png = name + '.png'
        name_png = os.path.join(png_file, name_png)
????????download_image(name_webp,?name_png,?img_url)

球点赞

相关推荐

vue 基础-组件中事件的触发和监听

前言《vue基础》系列是再次回炉vue记的笔记,除了官网那部分知识点外,还会加入自己的一些理解。(里面会有部分和官网相同的文案,有经验的同学择感兴趣的阅读)vue中单纯的事件调用,你一定不陌生...

JMH基准测试和JMH-Visual-chart可视化

原文地址:https://github.com/Sayi/sayi.github.com/issues/68如何度量一段代码的性能,换种实现方式会有更佳的性能表现吗?你或许想知道fastjson是否正...

一文轻松看懂丰田汽车的电路图(丰田车电路图识读技巧)

丰田汽车电路图符号、含义丰田汽车电路图识读说明电路图中字母是注释标号,其各部分的含义如下:注释标号A:表示系统标题,在电路图上方用横线划分,区域内用文字和系统符号表示下方电路系统的名称。注释标号B:表...

杭州高级中学发文言文版校庆公告引热议——全文932字,74处注释

阅读提示校方回应:我们期待以这种‘复古’的方式引起公众注意,也算是为树立起大众的文化自信、唤起大众对传统文化的关注作出一点贡献。5月14日,杭州高级中学官方微信发布了一篇文言文版的校庆公告。几个小...

Python 和 JS 有什么相似?(python和js哪个快)

Python是一门运用很广泛的语言,自动化脚本、爬虫,甚至在深度学习领域也都有Python的身影。作为一名前端开发者,也了解ES6中的很多特性借鉴自Python(比如默认参数、解构赋值、...

阿里卖家 Flutter for Web 工程实践

作者:马坤乐(坤吾)Flutter自2015年初次亮相以来,经过了多年的发展已经相当成熟,在阿里、美团、拼多多等互联网公司都有广泛的应用。在ICBU阿里卖家上90+%的新业务使用Flu...

诗经275思文押韵、注释、古音、今韵

诗经275-1思文押韵(备注:□=非韵、■=i韵、●=o/u韵、◆=ng韵、=i/o二象性)「」1.思文后稷,克配彼天。立我烝民,莫菲尔极。贻我来牟,帝命率育。无此疆尔界,陈常于时夏。□□□■,...

SolidWorks中常用命令快捷键(solidworks有哪些快捷键)

1.A:中心线2.B:镜向3.C:画圆4.D:智能标柱尺寸5.E:删除6.F:草图倒圆角7.G:画直线8.H:从装配制作工程9.I:等距实体10.J:从装配制作装配11.K:多边形12.L:延伸13....

第一章、TS语言简介(tsl语言)

TypeScript(简称TS)是微软公司开发的一种基于JavaScript(简称JS)语言的编程语言。它的目的并不是创造一种全新语言,而是增强JavaScript的功能,使其更适合多人合...

为什么要用JMH?何时应该用?(日本jmh地面分析图网站)

if快还是switch快?HashMap的初始化size要不要指定,指定之后性能可以提高多少?各种序列化方法哪个耗时更短?无论出自何种原因需要进行性能评估,量化指标总是必要的。在大部分场合...

雅虎“YSlow - 23 条规则”详尽阐释

以下乃是雅虎“YSlow-23条规则”的详尽阐释,旨在优化网页之性能以及用户之体验,乃是结合技术之原理与实践之方法梳理而成:1.减少HTTP请求次数说明:每一次HTTP请求皆会增添延迟...

JavaScript 运算符(js ~运算符)

JavaScript运算符JS变量JS算数JavaScript运算符实例向变量赋值,并把它们相加:varx=7;//向x赋值5vary=8;//向y赋值2...

在Notebook中使用Sublime Text 快捷键

编程派微信号:codingpy前几天,我在公众号上发布了两篇译文,对JupyterNotebook做了一些基础性的介绍。虽然说比较基础,而且第二篇阅读量并不高,但是我认为对于其他对于Noteb...

晨光静好时!2 道 JS 与 TS 面试题解析,开启惬意学习日

当第一缕晨光温柔地唤醒窗台的绿植,泡上一杯清香四溢的茉莉花茶,坐在洒满阳光的角落。此刻,放下对面试的焦虑,让我们像聊生活趣事般,轻松拆解两道JavaScript和TypeScript的高频面试...

2024年CSPJ题目解析,语法基本功>算法!

前言:每次有家长来找我们咨询报课,说孩子学了一年了,竞赛成绩不理想,问怎么才能强化,提升,我们经过一番询问,发现这类孩子普遍都是在算法上已经花了非常多的时间了,但是语法根本不过关。对这种孩子我们普遍建...