声明: 本文档只做案例演示, 程序运行设置有时间间隔.
分析目标网站结构
本次爬取的网站是国家航天局
我们的目标是下载该网站精彩图集中的图片.
每页和图片详情页URL的分析
通过观察我们可以发现, 精彩图集页面下, 一共有14页, 每页都包含了相关的图片. 点击这些图片我们能进入到图片详情页, 详情页中包含了目标图片和图片标题.
既然能通过点击对应图片进入到图片详情页, 说明当前页面中包含了图片详情页的URL.
精彩图集中一共14页, 说明我们需要爬取14个页面中的图片详情页URL.
通过分析网站发现, 精彩图集中点击进入下一页, 或者点击第二页, 第三页. 浏览器上方的网址(URL)并没有发生变化, 但是实际在换页的时候, 页面上的图片是会发送变化的. 根据这个现象可以猜测网站在进入下一页或其他页面时会发送额外的请求来获取页面上需要呈现的图片数据, 如ajax请求.
打开浏览器的开发者工具, 在network中对请求进行简单抓包分析, 发现进入下一页的时候会有额外请求的发送, 而这些额外请求返回的响应中包含了图片的详情页链接
我们可以看到这些请求返回的数据是一堆html代码, 而这些代码中包含了a标签, 标签中href属性的值就是图片详情页的URL, 当然这个URL是残缺的, 我们需要进行相关的拼接, 因为实际的详情页URL一般是这样的: http://www.cnsa.gov.cn/n6758823/n6758842/c6769934/content.html
既然图片详情页的URL就在这些请求返回的响应中, 那么也就是说我们模拟这些请求来获取响应即可, 从响应中提取我们要的数据.
详情页URL搞定了, 我们要想一想整个精彩图集的每一页应该怎么爬取, 虽然我们肉眼直观的能看到是14页, 我们可以循环来发送刚才我们抓到的额外请求, 但是网站是会更新的, 一段时间后可能就不是14页. 我们要想个办法, 让程序自己在爬取的时候知道总页数是多少, 这样任何时候总页数都是正确的, 那么我们在爬取每一页的时候就不容易出错.
在查看 精彩图集网页源代码的时候, 发现html代码中包含了一段js代码, 里面定义了总页数的变量.
显然maxPageNum = 14;这里变量的值就是我们想要的总页数, 我们可以通过访问该页面, 使用正则来匹配该变量值获取总页数.
总结: 分析到这里, 我们解决了爬取图片的两个问题.
发现额外发送的请求中包含了图片的URL, 可以通过让程序发送这些请求来获取图片URL.
从精彩图集首页中的源代码中发现总页数的数据所在位置, 通过正则可以来提取总页数.
这样我们离下载图片还差访问详情页和访问页中的图片URL了.
图片详情页分析
通过浏览器开发者工具, 我们能轻易的查看到图片URL所在网页代码中的位置, 我们发现图片URL就在img标签中, 大致的层次结构如图, 现在的话我们就打开网页源代码, 看下网页源代码中是否也能直接找到这样的URL.
显然我们直接就找到了, 那么我们的图片URL找到了, 而且我们图片的标题也是能在源代码中找到的.
所以总结: 到目前为止, 我们整个网站分析就结束了.
图集总页数的数据获取
图集每一页的请求的抓取, 详情页URL的确定.
详情页中图片URL和图片标题的确定.
接下来就剩写代码了.
代码编写
首先创建demo3目录, 在该目录下创建images目录和pa_china_sa.py文件.
该py文件中存放我们的爬虫代码.
我们分段处理问题来写代码
每一页请求的发送
代码需要安装导入并使用requests模块: pip install requests
这里的主要逻辑为:
访问图集首页
通过正则获取总页数.
通过总页数和构造每页URL再配合使用for循环, 来发送每页的请求
图片详情页的提取
代码需要安装导入并使用lxml模块: pip install lxml
lxml模块包含了支持xpath表达式的功能, 可以通过该模块配合xpath来提取结构化的数据即详情页URL
主要逻辑为:
根据每页返回响应数据, 创建支持xpath的对象, 并提取URL.
对提取的数据进行请求.
从图片详情页中提取图片URL
主要逻辑为:
通过xpath从循环请求详情页的响应中抽取图片URL和图片标题.
通过列表的追加方法, 将图片的URL和名称放入到列表中.
下载图片并保存到images目录下
代码可以封装到函数中, 使用上多线程来提高下载效率.
from multiprocessing.pool import ThreadPool
执行结果如下:
有问题欢迎留言评论.有建议或者意见欢迎斧正 不胜感激
有兴趣一起学习爬虫的小伙伴们记得加群: 657598389,会有许多的资源可以供大家学习分享,欢迎大家前来一起学习进步!