python3爬虫爬取必应每日高清壁纸
一、简介
==必应==是微软推出的搜索引擎,相比于百度具有==广告少==的显著优点,比较==良心==。以下为必应的网址:https://cn.bing.com/
经常使用必应应该可以发现,其主页每天都会更新一张图片,博主发现这些图片非常符合博主的审美,希望每天能够下载收藏每张图片。幸运的是已经有人完成了这项工作,具体请看这个网站:必应每日高清壁纸(https://bing.ioliu.cn/)。
这个网站收录了必应每天的主页图片,并且提供==直接下载==(管理猿太良心了,祝愿少掉一些头发,少写一些bug🤭🤭🤭)。但是博主发现这个网站缺少一个==一键全部下载功能==,只能一张一张图片==手动下载==,如果要把所有图片都下载下来,非常麻烦,因此用==python==写了一个下载网站上所有图片的小爬虫,分享给大家。
二、使用的环境
- python3.8.1(较新版本都可)
- requests库(需要使用pip工具下载该库)
- re库(python自带,不用下载,直接导入就行)
- bs4库(需要使用pip工具下载该库)
三、网页分析
1、分析网页每一页url形式以及总页数
在主页的最后可以看到有下一页的信息,如下图,
在这里可以收集到网页的==最大页数信息==,用以后续生成每一页的==url链接==。点击下一页,可以看到url变成:
容易推理出来对于不同页面网页的url形式为:
1 | url = 'https://bing.ioliu.cn/?p={}'.format(page_count) |
2、网页重要信息收集
打开必应每日高清壁纸,鼠标悬停在任意一张图片上面可以看到出现以下信息:
这其中对于我们较为重要的信息是==图片介绍信息==以及==网页下载按钮所对应的url链接==,因为我们需要把图片介绍信息作为下载图片的文件名,这样容易预览和区分。
3、在源码中寻找所需信息的位置
打开网页调试工具,打开任意一页,通过调试可以发现,每一张图片的信息主要在==body标签==下==class属性为container的div标签==中:
打开div标签可以看到子节点==并列==存放着==class属性为item的div标签==,每一个子标签存放的就是每一张图片的信息。如下图:
这其中==description属性的div标签==存放的就是关于==图片的描述信息==,而==options属性的div==标签存放的就有==图片的下载链接==。如下图:
最后我们还需要知道网页的==最大页面数的标签==的位置,通过调试发现位于==span标签==下,如图:
找到了这些重要信息的位置之后,就可以开始敲代码了!
四、代码实现
代码主要包括五个函数:
- ==GetHtmlText(url)==:根据传入的==url链接==发送http请求,并返回获取的数据,后面很多函数都要用到,这里为了防止被服务器检测到是爬虫,建议尽量多写一些附加信息,尽量模拟浏览器的浏览操作。
1 | def GetHtmlText(url): |
- ==GetMaxPageCount()==:根据主页信息获得网页的最大页数,利用==BeautifulSoup==解析网页结构。
1 | def GetMaxPageCount(): |
- ==SavePictureInUrl(pic_url,pic_name,pic_path)==:根据传入的==url链接==请求并获得图片的数据,然后根据==文件名==和==文件路径==将图片数据写入到对应的文件中,这里需要注意的是图片属于二进制文件,因此要以二进制文件的方式打开和写入。
1 | def SavePictureInUrl(pic_url,pic_name,pic_path): |
- ==GetOnePageJpg(page_count, pic_path)==:根据当前传入的页码==自动生成==对应的url链接,然后请求并获得相应的数据,解析结构后获得图片的信息,==拼接成文件的名称==,这里要注意windows规定某些特殊字符不能用作文件名,需要加以剔除,不然会出问题。然后获取图片的下载地址并==拼接成完整的url地址==,将这些信息传入以上函数就能获得图片。
1 | def GetOnePageJpg(page_count, pic_path): |
==GetAllPageJpg(pic_path)==:传入==文件的保存地址==,然后获取所有网页的图片,主要是调用前面的函数。
1
2
3
4
5
6def GetAllPageJpg(pic_path):
# 爬取所有的图片,并保存在输入的路径参数下
max_page_count = GetMaxPageCount()
for page_index in range(1, max_page_count):
GetOnePageJpg(page_index, pic_path)
print('\r', '正在获取,已完成:{:.2f} %'.format(page_index/max_page_count*100), end = '', flush=True) #输出进度信息main():最后编写和调用main函数就能完成。
1
2
3
4
5def main():
# 程序执行
pic_path = 'E://bing图片/' #文件保存路径
GetAllPageJpg(pic_path)
main() #执行main函数
五、运行爬虫
windows运行该脚本首先win+R打开运行,然后输入cmd打开控制台,将工作文件夹切换到脚本所在文件夹,然后输入命令:
1 | python bingjpg.py |
即可运行该脚本(前提是电脑已经安装好了python环境)。
万万没想到,这个网站居然有反爬机制?!脚本运行一段时间,下载了21.21%出现403错误🤣🤣🤣,仅仅下载了部分图片。
此时在浏览器打开网页也被禁止访问,应该是ip被禁了!!!不过目前大多数宽带都是使用==DHCP服务生成动态ip==,一般==2个小时==之后ip会自动更换,或者直接==重启路由器==也可以立即更换ip,更换了ip地址之后又能访问该网站。
针对这一情况推测网站很有可能是根据==下载请求的速度==以及==数量==来判断爬虫,从而封禁ip,后面可以利用前面已经写好的函数从后续页开始爬取,稍微改动代码就行,不用又从头开始。
六、后续改进
后续该爬虫还有两个方面可以改进:
- 爬取一次中断之后重新爬取时,之前爬取的图片又要重新爬取,费时费力,后面可以加一个判断,如果当前文件夹中已经存在该图片,就不再爬取,直接跳过。
- 适当降低爬取速度,每爬取一张图片之后sleep一段时间,防止被反爬程序检测到。