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

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

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

下期见咯~

相关推荐
weixin_466485112 分钟前
PyCharm中运行.py脚本程序
ide·python·pycharm
Jay_2732 分钟前
python项目如何创建docker环境
开发语言·python·docker
老胖闲聊1 小时前
Python Django完整教程与代码示例
数据库·python·django
爬虫程序猿1 小时前
利用 Python 爬虫获取淘宝商品详情
开发语言·爬虫·python
noravinsc1 小时前
django paramiko 跳转登录
后端·python·django
声声codeGrandMaster1 小时前
Django之表格上传
后端·python·django
元直数字电路验证1 小时前
Python数据分析及可视化中常用的6个库及函数(一)
python·numpy
waterHBO1 小时前
一个小小的 flask app, 几个小工具,拼凑一下
javascript·vscode·python·flask·web app·agent mode·vibe coding
智商不够_熬夜来凑1 小时前
anaconda安装playwright
开发语言·python
溜溜刘@♞1 小时前
python变量
python