当前位置: 首页 > news >正文

【Python从入门到进阶】50、当当网Scrapy项目实战(三)

接上篇《49、当当网Scrapy项目实战(二)》
上一篇我们讲解了的Spider与item之间的关系,以及如何使用item,以及使用pipelines管道进行数据下载的操作,本篇我们来讲解Scrapy的多页面下载如何实现。

一、多页面下载原理分析

1、多页面数据下载主要思路

我们之前编写的爬虫,主要是针对当当网书籍详情首页的列表数据进行下载,也只能下载第一页已经加载好的列表数据:

如果我们想要下载该种书籍的多页数据(例如1到100页)的数据,这就涉及到爬虫的多页面下载逻辑了。

我们现在可以思考一下,我们下载从第1页到第100页的书籍详情列表数据,数据结构和取数逻辑是否是一样的?答案是一样的。
所以我们在爬虫文件中编写的数据列表数据获取逻辑是核心程序,是不需要修改的,我们只需要把每一页的新内容传输给它,它进行数据转换清洗,变成数据结构对象,最后存储到文件中去即可。如同下图:

我们要做的事情,就是在爬虫中parse函数执行第1页请求完毕后,再使用parse函数执行第2页、第3页等等的请求即可。

2、如何获取多个页面的数据

我们如何来获取第2页及之后的数据呢?首先我们进入图书列表页,分别点击后面的第2页、第3页,并记录一下浏览器上面的地址:

我们分别看一下第1页、第2页、第3页的网址:

聪明的童鞋应该可以看出区别了吧,没错,从第1页之后,每页页面在“cp01”前会有一个“pgx-”,而其中的“x”就是当前的页码数。所以我们要获取某一页的数据,就只需要修改“pg”后面的数字为几,即可拿到相关页面的数据了。

二、多页面下载程序编写

1、指定相关路径

此时我们在爬虫文件中,就需要指定起始页面是什么,然后后续的迭代页面是什么,代码如下:

class DangSpider(scrapy.Spider):name = "dang"# 如果为多页下载,必须将allowed_domains的范围调整为主域名allowed_domains = ["category.dangdang.com"]start_urls = ["http://category.dangdang.com/cp01.22.01.00.00.00.html"]base_url = 'http://category.dangdang.com/pg'end_url = '-cp01.22.01.00.00.00.html'page = 1#......下面代码省略......

其中的base_url是迭代页面的主地址信息,end_url是页码获取后拼接的静态页面固定地址,page是下一次要抓取的页面的页码数。

2、编写多页面下载判定与执行逻辑

然后我们在之前parse函数结束中的for循环结束后,编写一个页面判断的逻辑(注意是在for循环的外面,parse函数的里面):

if self.page < 100:  # 判断当前页面是否在100页以内self.page = self.page + 1  # 获取下一个页码# 根据获取的页码,拼接下一个需要爬取的页面url地址url = self.base_url + str(self.page) + self.end_url# 回调爬虫的parse函数,用新的url继续进行数据爬取# scrapy.Request就是scrapy的get请求# 其中的url是请求地址,callback是需要执行的爬虫的函数,注意不需要加圆括号yield scrapy.Request(url=url,callback=self.parse)
3、测试效果

这是我们删除原来抓取的book.json中的所有数据,清理下载的书籍图片,然后通过“scrapy crawl dang”命令执行我们的dang.py爬虫:

程序执行后,可以看到爬虫在逐页爬取相关数据:

等待爬虫执行完毕(这里我爬了101页,是因为上面小于100写成小于等于了):

我们可以看到json文件又被写满了:

其中最后一个数据,和当前网站的第100页的数据基本吻合:

查看一下图片,发现也是全部下载下来了(1页60条数据,100页共6000张封面,我们下载了5700多张),说明1到100页的数据已经基本全部抓取过来了:

4、完整代码

下面是刚刚上面优化完毕后的Scrapy爬虫逻辑的完整代码:

import scrapyfrom scrapy_dangdang_01.items import ScrapyDangdang01Itemclass DangSpider(scrapy.Spider):name = "dang"# 如果为多页下载,必须将allowed_domains的范围调整为主域名allowed_domains = ["category.dangdang.com"]start_urls = ["http://category.dangdang.com/cp01.22.01.00.00.00.html"]base_url = 'http://category.dangdang.com/pg'end_url = '-cp01.22.01.00.00.00.html'page = 1def parse(self, response):# 获取所有的图书列表对象li_list = response.xpath('//ul[@id="component_59"]/li')# 遍历li列表,获取每一个li元素的几个值for li in li_list:# 书籍图片src = li.xpath('.//img/@data-original').extract_first()# 第一张图片没有@data-original属性,所以会获取到控制,此时需要获取src属性值if src:src = srcelse:src = li.xpath('.//img/@src').extract_first()# 书籍名称title = li.xpath('.//img/@alt').extract_first()# 书籍作者search_book_author = li.xpath('./p[@class="search_book_author"]//span[1]//a[1]/@title').extract_first()# 书籍价格price = li.xpath('./p[@class="price"]//span[@class="search_now_price"]/text()').extract_first()# 书籍简介detail = li.xpath('./p[@class="detail"]/text()').extract_first()# print("======================")# print("【图片地址】", src)# print("【书籍标题】", title)# print("【书籍作者】", search_book_author)# print("【书籍价格】", price)# print("【书籍简介】", detail)# 将数据封装到item对象中book = ScrapyDangdang01Item(src=src, title=title, search_book_author=search_book_author, price=price, detail=detail)# 获取一个book对象,就将该对象交给pipelinesyield bookif self.page < 100:  # 判断当前页面是否在100页以内self.page = self.page + 1  # 获取下一个页码# 根据获取的页码,拼接下一个需要爬取的页面url地址url = self.base_url + str(self.page) + self.end_url# 回调爬虫的parse函数,用新的url继续进行数据爬取# scrapy.Request就是scrapy的get请求# 其中的url是请求地址,callback是需要执行的爬虫的函数,注意不需要加圆括号yield scrapy.Request(url=url,callback=self.parse)

至此,关于Scrapy实战项目的多页数据下载的内容就全部介绍完毕。下一篇我们来讲解电影天堂网站的多页面下载,继续巩固一下多页面下载技术。


参考:尚硅谷Python爬虫教程小白零基础速通
转载请注明出处:https://guangzai.blog.csdn.net/article/details/136605061

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Midjourney绘图欣赏系列(七)
  • [2023年]-hadoop面试真题(一)
  • 【py】加载sdk文件夹中的dll
  • 蓝桥杯2023年-平方差(数学)
  • 谷歌开源的LLM大模型 Gemma 简介
  • Elasticsearch 通过索引阻塞实现数据保护深入解析
  • 网络安全: Kali Linux 进行 SSH 渗透与防御
  • pyqt线程正确使用
  • MyBatisPlus理解
  • 代码随想录 贪心算法-简单题目
  • Unity 整体界面淡入淡出效果
  • 服务器又被挖矿记录
  • 深入理解Servlet
  • 封装SDK时如何隐藏内部符号
  • bacnet cov机制详细介绍
  • css属性的继承、初识值、计算值、当前值、应用值
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • LeetCode18.四数之和 JavaScript
  • PAT A1092
  • php ci框架整合银盛支付
  • PHP CLI应用的调试原理
  • php面试题 汇集2
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 分类模型——Logistics Regression
  • 开源SQL-on-Hadoop系统一览
  • 深入浏览器事件循环的本质
  • 深入浅出Node.js
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 昨天1024程序员节,我故意写了个死循环~
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • ​Spring Boot 分片上传文件
  • (C#)一个最简单的链表类
  • (day18) leetcode 204.计数质数
  • (编译到47%失败)to be deleted
  • (二)Linux——Linux常用指令
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • .net 调用海康SDK以及常见的坑解释
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • @Repository 注解
  • @ResponseBody
  • [BJDCTF2020]Easy MD51
  • [Bugku] web-CTF靶场系列系列详解⑥!!!
  • [BZOJ 4129]Haruna’s Breakfast(树上带修改莫队)
  • [CF703D]Mishka and Interesting sum/[BZOJ5476]位运算
  • [cvpr 2024 目标检测 前沿研究 热点] cpvr 2024中与目标检测主题有关的论文
  • [go] 策略模式
  • [HackMyVM]靶场 Wild
  • [HarmonyOS]第一课:从简单的页面开始
  • [leetcode] 四数之和 M
  • [Luogu P3527BZOJ 2527][Poi2011]Meteors(整体二分+BIT)
  • [NOI 2016]优秀的拆分