Python爬虫实战案例(1)—— 爬取百度图片 及 其它网站的网页图片

嘿,大伙~ 学了四期Python爬虫的基础内容,我们已经能够在一定程度上独当一面了,所以今天这一期我们就开始实战一下吧!~

对前面三章的补充

前面三期里,我们讲了我们会用到的三个页面解析的方法。

那么问题来了------

什么时候需要用到我们的页面解析的方法呢?

我们打开页面源代码,然后在里面搜索,如果能搜到,那就能用页面解析,不论是Bs4还是Xpath亦或是正则,都是可以的。

这一期里,我们通过爬取三个网站的图片,来简单接触一下怎么爬取网页中的图片,以及怎么存储到本地。

首先第一个网页我们来一点点尝试吧~

哲风壁纸

第一个就它了。

访问网页

首先,我们先访问进到这个网页里面。

这一步,如果有疑惑的,可以翻看前面爬虫的第一期,链接在下面。
Python爬虫学习第一弹 ------ 爬虫的基础知识 及 requests基础

headers

这个网页没有那么多检测,只需要user-agent就行了。

代码

python 复制代码
import requests

url ='https://haowallpaper.com/?isSel=false&page=1'

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
}

html = requests.get(url, headers=headers).text
print(html)

页面解析

主要就是通过,检查里面左上角的那个箭头,指到我们要查询的画面内容上,然后写出它的Bs4或者Xpath的搜索式------

Bs4表达式

div.homeContainer div.card img

我比较喜欢用Bs4写,这里就放我用Bs4写的结果,当然其它的方法也都是可以的, 大家选择自己喜欢的方式就行了。

这里的部分大家可以看看前面三期,选择自己喜欢的方式写就行了。
Python爬虫学习第二弹 ------ Beautiful Soup页面解析
Python爬虫学习第三弹 ------ Xpath 页面解析 & 实现无广百·度
Python爬虫学习第四弹 ------ 正则表达式 获取 知乎热榜

代码

python 复制代码
import requests
from bs4 import BeautifulSoup

url ='https://haowallpaper.com/?isSel=false&page=1'

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
}

html = requests.get(url, headers=headers).text

soup = BeautifulSoup(html, 'lxml')
res = soup.select('div.homeContainer div.card img')

for i in res:
    print(i.get('title'))
    print(i.get('src'))

下面我们来看看怎么把它保存到我们的本地。

文件存储

创建文件夹

python 复制代码
import os
if not os.path.exists('./haowallpaper'): #如果不存在haowallpaper文件夹
    os.mkdir('./haowallpaper') #就生成这个文件夹

基本都是通用的,大家就记住这样写吧,ctrl + c & ctrl + v 走天下。

访问下载图片

我们把获取到的图片链接直接在浏览器打开,我们会发现是能够直接获取到的,说明它没有什么加密。

python 复制代码
img_url = i.get('src')
img = requests.get(img_url)

文件存储

python 复制代码
with open('./haowallpaper/%s.jpg' % i.get('title'), 'wb') as f:
    img_url = i.get('src')
    img = requests.get(img_url)
    f.write(img.content)

记得一定要加后缀 .jpg 或者 其它图片格式

代码

python 复制代码
import requests
import os
from bs4 import BeautifulSoup

if not os.path.exists('./haowallpaper'):
    os.mkdir('./haowallpaper')

url ='https://haowallpaper.com/?isSel=false&page=1'

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
}

html = requests.get(url, headers=headers).text

soup = BeautifulSoup(html, 'lxml')
res = soup.select('div.homeContainer div.card img')

for i in res:
    print('正在下载:' + i.get('title'))
    with open('./haowallpaper/%s.jpg' % i.get('title'), 'wb') as f:
        img_url = i.get('src')
        img = requests.get(img_url)
        f.write(img.content)
    print('下载完成。')

效果就是这样子。

多页面存储

可以观察到,各个页面下我们网址的变化就只有page,所以我们遍历一下,就可以获取多个页面的图片了。

代码

python 复制代码
import requests
import os
from bs4 import BeautifulSoup

if not os.path.exists('./haowallpaper'):
    os.mkdir('./haowallpaper')
page = 1
while True:
    url =f'https://haowallpaper.com/?isSel=false&page={page}'

    headers = {
        'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    }

    html = requests.get(url, headers=headers).text

    soup = BeautifulSoup(html, 'lxml')
    res = soup.select('div.homeContainer div.card img')

    for i in res:
        print('正在下载:' + i.get('title'))
        with open('./haowallpaper/%s.jpg' % i.get('title'), 'wb') as f:
            img_url = i.get('src')
            img = requests.get(img_url)
            f.write(img.content)
        print('下载完成。')
    x = input("按任意键继续下载,按!结束")
    if x == '!':
        break
    else:
        page += 1

效果就是这样子。

图怪兽

下一个,下一个。

上面的步骤我们就不多说了,我们这里就直接展示结果。

访问页面

python 复制代码
import requests

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

url = 'https://818ps.com/muban/all&0_0_0_0&k_kaigongdaji?top_id=5881371'
html = requests.get(url, headers=headers).text

页面解析

div.searchTemplate_flow_wrap__dGnCV div.searchTemplate_column__Ves_p div.searchTemplate_cart_wrap__1yDpm div.searchTemplate_scroll-wrap__KeGk5 div img

python 复制代码
import requests
from bs4 import BeautifulSoup

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

url = 'https://818ps.com/muban/all&0_0_0_0&k_kaigongdaji?top_id=5881371'
html = requests.get(url, headers=headers).text

soup = BeautifulSoup(html, 'lxml')
imgs = soup.select('div.searchTemplate_flow_wrap__dGnCV div.searchTemplate_column__Ves_p div.searchTemplate_cart_wrap__1yDpm div.searchTemplate_scroll-wrap__KeGk5 div img')

for img in imgs:
    img_alt = img.get('alt')
    img_src = img.get('src')
    print(img_alt)
    print(img_src)

文件存储

python 复制代码
import requests
import os
from bs4 import BeautifulSoup

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

if not os.path.exists('./818ps'):
    os.mkdir('./818ps')

url = 'https://818ps.com/muban/all&0_0_0_0&k_kaigongdaji?top_id=5881371'
html = requests.get(url, headers=headers).text

soup = BeautifulSoup(html, 'lxml')
imgs = soup.select('div.searchTemplate_flow_wrap__dGnCV div.searchTemplate_column__Ves_p div.searchTemplate_cart_wrap__1yDpm div.searchTemplate_scroll-wrap__KeGk5 div img')

for img in imgs:
    img_alt = img.get('alt')
    img_src = img.get('src')
    print('正在下载:', img_alt)
    with open('./818ps/{}.jpg'.format(img_alt), 'wb') as f:
        f.write(requests.get(img_src, headers=headers).content)
    print('下载完成', img_alt)

到这里,我们就写成了和上面的一样,但是我们会发现它报错了。

我们看看上面的img_src。

我们会发现,它少了前面http那一些,虽然我们直接打开这个网址是能打开的,但是从这里,我们是不行的,所以我们要加上前缀。

还有这个是我们前面的Bs4的语句写的不完善,但是在那边不是很好改,我们就直接在代码里面加一个判断就好。

代码

python 复制代码
import requests
import os
from bs4 import BeautifulSoup

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

if not os.path.exists('./818ps'):
    os.mkdir('./818ps')

url = 'https://818ps.com/muban/all&0_0_0_0&k_kaigongdaji?top_id=5881371'
html = requests.get(url, headers=headers).text

soup = BeautifulSoup(html, 'lxml')
imgs = soup.select('div.searchTemplate_flow_wrap__dGnCV div.searchTemplate_column__Ves_p div.searchTemplate_cart_wrap__1yDpm div.searchTemplate_scroll-wrap__KeGk5 div img')

for img in imgs:
    img_alt = img.get('alt')
    img_src = 'https:' + img.get('src')
    if img_alt:
        print('正在下载:', img_alt)
        with open('./818ps/{}.jpg'.format(img_alt), 'wb') as f:
            f.write(requests.get(img_src, headers=headers).content)
        print('下载完成', img_alt)

效果就是这样,

这个如果想要继续下载,也能够翻页,和上面的操作基本是一样的,这里就不赘述了。

百度图片

下面是我们今天的最后一个网页图片了,百度还是有牌面的,压轴了也是。

差异

这个和前面两个有一个本质上的区别:它是一个 ajax 动态加载 ,也叫做瀑布流

什么意思呢?

大家很容易就能观察到,在我们页面中,随着我下翻页面,它的内容是一点点更新出来。

那么对于这种我们要怎么去获取,这种的存储都通过json文件来进行存储的。

所以我们只需要抓到存储图片内容的json文件的包就行了。

抓 json 包

我们进到检查的网络板块,然后不断下翻我们的百度图片的页面,然后筛选一下

Fetch/XHR

我们会看到这些就是我想要的存储内容了。

但是它存储之中有很多个都是,那么我们怎么把所有都给弄下来呢??

大伙,观察一下我们会发现它的 url 里唯一改变的就只有 pncurPageNum ,很好理解,这就是翻页了。

所以,我们只需要写一个循环来遍历一下这个载荷就可以了。

那么,我们动手吧!~

代码

这次的代码,我们尝试一下前面 params 传递的方式。

params 也就是载荷里的内容。

如果,我们直接复制它的url,我们会发现我们爬不下来东西,因为其中搜索的部分被它转换成了对应编码,如果要用这种方式,我们要把编码换回中文。

python 复制代码
"""
ajax 动态加载 瀑布流
 ------>>> 寻找json文件。

"""

import requests

url = 'https://image.baidu.com/search/albumsdata?'

params = {
    'pn': '90',
    'rn': '30',
    'tn': 'albumsdetail',
    'word': '城市建筑摄影专题',
    'album_tab': '建筑',
    'album_id': '7',
    'ic': '0',
    'curPageNum': '3'
}

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36'
}

html = requests.get(url, params=params)

print(html.json())

到这里,我们就把其中一个 json包 爬下来了。

那么下一步,就是进行存储,这里的操作和前面是一样的。

文件存储

来看看我是怎么做的吧~

代码

python 复制代码
"""
ajax 动态加载 瀑布流
 ------>>> 寻找json文件。

"""

import requests
import os

if not os.path.exists('./baidu'):
    os.mkdir('./baidu')

url = 'https://image.baidu.com/search/albumsdata?'

params = {
    'pn': '90',
    'rn': '30',
    'tn': 'albumsdetail',
    'word': '城市建筑摄影专题',
    'album_tab': '建筑',
    'album_id': '7',
    'ic': '0',
    'curPageNum': '3'
}

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36'
}

html = requests.get(url, params=params).json()


for res in html['albumdata']['linkData']:
    img_pid = res['pid']
    img_url = res['thumbnailUrl']
    print('正在下载:', img_pid)
    with open('./baidu/{}.jpg'.format(img_pid), 'wb') as f:
        f.write(requests.get(img_url, headers=headers).content)
    print('下载完成', img_pid)

多文件存储

按照前面所说,我们只需要把 pncurPageNum 进行遍历即可。

这个也是和前面说的差不多,大家可以试试,如果不行,那就看看我的写法吧!~

代码

python 复制代码
"""
ajax 动态加载 瀑布流
 ------>>> 寻找json文件。

"""

import requests
import os

if not os.path.exists('./baidu'):
    os.mkdir('./baidu')

url = 'https://image.baidu.com/search/albumsdata?'

for i in range(5):
    params = {
        'pn': str(i * 30),
        'rn': '30',
        'tn': 'albumsdetail',
        'word': '城市建筑摄影专题',
        'album_tab': '建筑',
        'album_id': '7',
        'ic': '0',
        'curPageNum': str(i)
    }

    headers = {
        'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36'
    }

    html = requests.get(url, params=params).json()

    for res in html['albumdata']['linkData']:
        img_pid = res['pid']
        img_url = res['thumbnailUrl']
        print('正在下载:', img_pid)
        with open('./baidu/{}.jpg'.format(img_pid), 'wb') as f:
            f.write(requests.get(img_url, headers=headers).content)
        print('下载完成', img_pid)

效果

写完上面这个,我发现我们日常所使用到的百度图片不长这个样子。

所以,下面重新写一个。

新·百度图片

在我们从百度图片里找图片,遇到更多的都是这个样子的,所以这里重新写一个,大差没有,小差别还是有一些,所以就简单过一下。

抓json包

这里我们演示一下怎么直接改url。

python 复制代码
import requests
'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=12238656010602840941&ipn=rj&ct=201326592&is=&fp=result&fr=&word=%E5%A3%81%E7%BA%B8&cg=wallpaper&queryWord=%E5%A3%81%E7%BA%B8&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&expermode=&nojc=&isAsync=&pn=120&rn=30&gsm=78&1739954761925='
url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=12238656010602840941&ipn=rj&ct=201326592&is=&fp=result&fr=&word=壁纸&cg=wallpaper&queryWord=壁纸&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&expermode=&nojc=&isAsync=&pn=120&rn=30&gsm=78&1739954761925='

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36'
}

html = requests.get(url, headers=headers)
print(html.json())

文件存储

python 复制代码
import requests
import os

if not os.path.exists('./baidu'):
    os.mkdir('./baidu')

url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=12238656010602840941&ipn=rj&ct=201326592&is=&fp=result&fr=&word=壁纸&cg=wallpaper&queryWord=壁纸&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&expermode=&nojc=&isAsync=&pn=120&rn=30&gsm=78&1739954761925='

headers = {
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36'
}

html = requests.get(url, headers=headers).json()

for res in html['data']:
    if res: # 最后一个是空的,需要把它排除掉
        img_title = res['fromPageTitle']
        img_title = img_title.replace('|', '_').strip()
        img_url = res['hoverURL']
        if img_url: # 有一些没有提供 url,也需要排除掉
            print('正在下载:', img_title)
            with open('./baidu/{}.jpg'.format(img_title), 'wb') as f:
                f.write(requests.get(img_url, headers=headers).content)
            print('下载完成', img_title)

多文件存储

python 复制代码
import requests
import os

if not os.path.exists('./baidu'):
    os.mkdir('./baidu')

'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=12238656010602840941&ipn=rj&ct=201326592&is=&fp=result&fr=&word=%E5%A3%81%E7%BA%B8&cg=wallpaper&queryWord=%E5%A3%81%E7%BA%B8&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&expermode=&nojc=&isAsync=&pn=120&rn=30&gsm=78&1739954761925='

for i in range(1, 3): # pn为0的时候无法访问
    url = f'https://image.baidu.com/search/acjson?tn=resultjson_com&logid=12238656010602840941&ipn=rj&ct=201326592&is=&fp=result&fr=&word=壁纸&cg=wallpaper&queryWord=壁纸&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&expermode=&nojc=&isAsync=&pn={str(i * 30)}&rn=30&gsm=78&1739954761925='
    print(url)
    headers = {
        'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36'
    }

    html = requests.get(url, headers=headers).json()

    for res in html['data']:
        if res: # 最后一个是空的,需要把它排除掉
            img_title = res['fromPageTitle']
            img_title = img_title.replace('|', '_')
            img_title = img_title.replace(':', '_').strip()
            img_url = res['hoverURL']
            if img_url: # 有一些没有提供 url,也需要排除掉
                print('正在下载:', img_title)
                with open('./baidu/{}.jpg'.format(img_title), 'wb') as f:
                    f.write(requests.get(img_url, headers=headers).content)
                print('下载完成', img_title)

总结

OKk,本期的内容就到这里了,爬取网页图片,按照我们前面所获取的知识已经够了,大家多多练习,就可以轻松拿到喜欢的图片了。

感谢大伙观看,别忘了三连支持一下

大家也可以关注一下我的其它专栏,同样精彩喔~

下期见咯~

相关推荐
奔跑吧邓邓子20 分钟前
【Python爬虫(12)】正则表达式:Python爬虫的进阶利刃
爬虫·python·正则表达式·进阶·高级
码界筑梦坊43 分钟前
基于Flask的京东商品信息可视化分析系统的设计与实现
大数据·python·信息可视化·flask·毕业设计
pianmian11 小时前
python绘图之箱型图
python·信息可视化·数据分析
csbDD1 小时前
2025年网络安全(黑客技术)三个月自学手册
linux·网络·python·安全·web安全
赔罪3 小时前
Python 高级特性-切片
开发语言·python
伊一大数据&人工智能学习日志3 小时前
selenium爬取苏宁易购平台某产品的评论
爬虫·python·selenium·测试工具·网络爬虫
说是用户昵称已存在3 小时前
Pycharm+CodeGPT+Ollama+Deepseek
ide·python·ai·pycharm
Fansv5874 小时前
深度学习-2.机械学习基础
人工智能·经验分享·python·深度学习·算法·机器学习
wang_yb4 小时前
『Python底层原理』--Python对象系统探秘
python·databook
databook4 小时前
『Python底层原理』--Python对象系统探秘
后端·python