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

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

请添加图片描述

对前面三章的补充

前面三期里,我们讲了我们会用到的三个页面解析的方法。
那么问题来了——
什么时候需要用到我们的页面解析的方法呢?
我们打开页面源代码,然后在里面搜索,如果能搜到,那就能用页面解析,不论是Bs4还是Xpath亦或是正则,都是可以的。
在这里插入图片描述

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

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

图怪兽

下一个,下一个。
在这里插入图片描述
上面的步骤我们就不多说了,我们这里就直接展示结果。

访问页面

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

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)

文件存储

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的语句写的不完善,但是在那边不是很好改,我们就直接在代码里面加一个判断就好。

代码

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,我们会发现我们爬不下来东西,因为其中搜索的部分被它转换成了对应编码,如果要用这种方式,我们要把编码换回中文。

"""
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包 爬下来了。
那么下一步,就是进行存储,这里的操作和前面是一样的。

文件存储

来看看我是怎么做的吧~

代码

"""
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 进行遍历即可。
这个也是和前面说的差不多,大家可以试试,如果不行,那就看看我的写法吧!~

代码

"""
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。

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())

文件存储

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)

多文件存储

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

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

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

下期见咯~

请添加图片描述

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑不拉几的小白兔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值