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

接上篇《47、Scrapy Shell的了解与应用》
上一篇我们学习了Scrapy终端命令行工具Scrapy Shell,并了解了它是如何帮助我们更好的调试爬虫程序的。本篇我们将正式开启一个Scrapy爬虫项目的实战,对当当网进行剖析和抓取。

一、当当网介绍

当当网成立于1999年11月,是一家知名的综合性网上购物商城。从早期以图书业务为主的业务形态,逐步拓展到全品类百货,包括图书音像、美妆、家居、母婴、服装和3C数码等几十个大类,数百万种商品。

二、需要抓取的页面分析

我们进入当当网首页,点击“图书”链接:

进入当当网图书分类专区首页:

可以看到左侧有很多图书的分类。
点击其中一个最末级分类(我选择的是“一般管理类”,网址为http://category.dangdang.com/cp01.22.01.00.00.00.html),可以看到具体的图书分类列表:

列表包含书籍图片、书籍标题、作者、出版社、评分、标签和简介等内容。拉到最下面可以看到具体的分页,默认我们在第1页,总计100页:

我们要做的事情,就是将这100页的全部的图书信息,给它全部抓取下来。在之前我们单独讲解爬虫的时候,可能工作量比较大,但是我们使用Scrapy框架的话,效率很高,接下来我们就进行实战。

三、创建当当网Scrapy项目

首先在工程目录下使用“scrapy startproject 项目名”指令创建项目。然后进入创建好的工程的spiders目录下,使用“scrapy genspider 爬虫名 起始url地址”指令创建一个名为“dang”的爬虫文件:

这是“dang”的爬虫文件生成的代码:

import scrapyclass DangSpider(scrapy.Spider):name = "dang"allowed_domains = ["category.dangdang.com"]start_urls = ["http://category.dangdang.com/cp01.22.01.00.00.00.html"]def parse(self, response):pass

我们来校验一下这个网站有没有反爬虫校验,我们把上面的“pass”更换为“print”,打印一些等于号,看看一会能不能正常获取:
   

 def parse(self, response):print("========================")

我们在控制台使用“scrapy crawl dang”执行爬虫,可以看到结果里包含我们打印的等于号:

这说明网站没有反爬虫机制,我们无需调整scrapy功能的配置文件来忽略爬虫警告了。

四、编写分类图书信息获取爬虫

上面的工程以及爬虫文件创建好后,我们就来编写分类图书信息获取的爬虫逻辑。
我们再来回顾一下之前讲解的scrapy的工程项目组成:

这里面我们就会用到item、pipelines等组件类了。

1、定义item数据结构

我们打开item.py文件,来定义我们的基础数据结构,通俗的来说就是我们需要下载的数据都有什么。这里我们根据页面剖析的结果,可以看到有以下几种数据:

我们在item.py文件定义相关的数据:

import scrapyclass ScrapyDangdang01Item(scrapy.Item):# 书籍图片src = scrapy.Field()# 书籍名称title = scrapy.Field()# 书籍作者search_book_author = scrapy.Field()# 书籍价格price = scrapy.Field()# 书籍简介detail = scrapy.Field()

2、分析spider爬取逻辑

我们分析书籍图片的地址xpath代码:

经过分析,获取每一页的所有图书的图片的xpath代码为:

//ul[@id="component_59"]/li//img/@src

同样的,获取书籍名称,可以直接从img的alt属性获取,xpath代码为:

//ul[@id="component_59"]/li//img/@alt

然后我们分析作者的数据:

获取作者的xpath代码为:

//ul[@id="component_59"]/li/p[@class="search_book_author"]//span[1]//a[1]/@title

然后我们分析价格的数据:

获取价格的xpath代码为:

//ul[@id="component_59"]/li/p[@class="price"]//span[@class="search_now_price"]/text()

最后我们分析书籍简介的数据:

获取书籍简介的xpath代码为:

//ul[@id="component_59"]/li/p[@class="detail"]/text()

3、编写spider爬虫代码

按照上面的分析,编写初步的spider爬虫代码,如下:

import scrapyclass DangSpider(scrapy.Spider):name = "dang"allowed_domains = ["category.dangdang.com"]start_urls = ["http://category.dangdang.com/cp01.22.01.00.00.00.html"]def parse(self, response):# 获取所有的图书列表对象li_list = response.xpath('//ul[@id="component_59"]/li')# 遍历li列表,获取每一个li元素的几个值for li in li_list:# 书籍图片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)

我们先运行爬虫打印一下,看看获取到的信息对不对:

发现相关信息确实获取到了,但是我们同时也注意到了一个问题,就是书籍图片的src地址,除了第一张外,后面的地址全部是重复的,都是“ images/model/guan/url_none.png”。这是因为网页使用了懒加载功能,除了第一个图片,其他的在往下翻网页的时候,才会获取到真正的图片。

那么我们真么破除懒加载,获取真正的图片地址呢?我们去网页分析一下书籍图片的html代码:

<img data-original="//img3m9.ddimg.cn/85/14/29491789-1_b_20.jpg" src="//img3m9.ddimg.cn/85/14/29491789-1_b_20.jpg" alt=" 金线(麦肯锡真正在用的管理工具。冯唐倾囊相授成事学修炼方法。)" style="display: block;" class="">

这里面的src属性,在没有往下拉网页前,里面的图片地址统一为“ images/model/guan/url_none.png”空图片,往下拉到它之后,src里面的内容才会变更为data-original中的地址(就像上面是一个已经加载过的图片,src和data-original属性的地址一样)。
所以,我们的图片地址需要更改为“data-original”属性,而不是原本的src,这样就可以破除懒加载的阻碍了:

# 书籍图片
src = li.xpath('.//img/@data-original').extract_first()

此时再去看结果,真实的图片地址就有了:

但是细心的朋友会发现,更改为“data-original”属性后,第一本书籍的图片地址就“空”了:

我们观察一下网页,发现第一个图书的图片信息汇总,没有“data-original”属性,只有一个src:

我们需要单独处理一下第一张图片的地址,代码优化如下:

 # 书籍图片
src = li.xpath('.//img/@data-original').extract_first()
# 第一张图片没有@data-original属性,所以会获取到空值,此时需要获取src属性值
if src:src = src
else:src = li.xpath('.//img/@src').extract_first()

修改之后,我们重新运行爬虫,此时可以看到获取到了第一张图片及后面所有图片的地址:

至此,第一部分就讲解完毕。下一篇我们继续编写该当当网的项目,讲解刚刚编写的Spider与item之间的关系,以及如何使用item,以及使用pipelines管道进行数据下载的操作。
            

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/654703.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】二叉搜索树的模拟实现

目录 1、概念 2、模拟实现 2.1、查找 2.2、插入 2.3、删除&#xff08;难点&#xff09; 3、性能分析 4、完整代码 1、概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有…

C语言实现基础数据结构——顺序表

目录 顺序表 顺序表和数组 顺序表的分类 静态顺序表 动态顺序表 静态顺序表和动态顺序表的比较 动态顺序表的实现 主要实现功能 顺序表的初始化 顺序表的销毁 顺序表的打印 顺序表的尾部插入 顺序表的头部插入 顺序表的尾部删除 顺序表的头部删除 顺序表的指定…

如何使用docker compose安装APITable并远程访问登录界面

文章目录 前言1. 部署APITable2. cpolar的安装和注册3. 配置APITable公网访问地址4. 固定APITable公网地址 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 …

Java基础常见面试题总结(下)

常见的Exception有哪些&#xff1f; 常见的RuntimeException&#xff1a; ClassCastException //类型转换异常IndexOutOfBoundsException //数组越界异常NullPointerException //空指针ArrayStoreException //数组存储异常NumberFormatException //数字格式化异常ArithmeticE…

Mysql-InnoDB-数据落盘

概念 1 什么是脏页&#xff1f; 对于数据库中页的修改操作&#xff0c;则首先修改在缓冲区中的页&#xff0c;缓冲区中的页与磁盘中的页数据不一致&#xff0c;所以称缓冲区中的页为脏页。 2 脏页什么时候写入磁盘&#xff1f; 脏页以一定的频率将脏页刷新到磁盘上。页从缓冲区…

教你一招,测试人员如何通过AI提高工作效率!

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

C++仿函数、万能头文件、transform学习

这是网上的一个代码,里面的一些东西以前没用过; #include <bits/stdc++.h> using namespace std;// A Functor class increment { private:int num; public:increment(int n) : num(n) { }int operator () (int arr_num) const {return num + arr_num;} };// Driver …

【破事水】Java Gradle 无法引入同名不同版本的两个包

此问题水于 2024 年 01 月&#xff0c;假如后面 gradle 出了什么好方法能解决这个问题&#xff0c;家祭无忘告乃翁&#xff0c;提前谢过看到这篇的各位大佬了。 结论 先说结论&#xff0c;Java 因为包名定义等原因&#xff0c;对同名包在编译时只能编译一个版本&#xff0c;具…

Kafka高级_生产者ACk机制数据一致性问题

Kafka高级_生产者ACk机制&数据一致性问题 目录需求&#xff1a; 设计思路实现思路分析1.Kafka高级_生产者ACk机制2.Kafka高级数据一致性问题 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c…

微信小程序开发学习笔记《13》WXS脚本

微信小程序开发学习笔记《13》WXS脚本 博主正在学习微信小程序开发&#xff0c;希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读对应官方文档 一、WXS介绍 WXS ( WeiXin Script)是小程序独有的一套脚本语言&#xff0c;结合WXML&#xff0c;可以构建出页面的…

CSDN COC·北京开发者社区2023年度聚会

CSDN COC北京开发者社区2023年度聚会 年末盛会&#xff1a;北京开发者社区2023年度聚会 1. 活动背景&#x1f389;2. 活动议程3. 活动亮点介绍 &#x1f31f;3.1 主理人开场破冰3.2 话题讨论&#xff1a;3.3 城市社区介绍、回顾与展望 &#x1f3d9;️4. 活动留念5.活动总结 博…

浅出深入-机器学习

文章目录 一、K近邻算法1.1 先画一个散列图1.2 使用K最近算法建模拟合数据1.3 进行预测1.4 K最近邻算法处理多元分类问题1.5 K最近邻算法用于回归分析1.6 K最近邻算法项目实战-酒的分类1.6.1 对数据进行分析1.6.2 生成训练数据集和测试数据集1.6.3 使用K最近邻算法对数据进行建…

计算机网络——路由信息协议 (RIP) 实验

1.实验题目 实验五&#xff1a;路由信息协议 (RIP) 实验 2.实验目的 &#xff08;1&#xff09;了解RIP的相关知识以及原理。 &#xff08;2&#xff09;掌握RIP路由的配置方法。 3.实验任务 (1) 路由器的基本配置&#xff1a;设置路由器接口 IP 地址。 (2) 根据以上拓扑…

Python Tornado 实现SSE服务端主动推送方案

一、SSE 服务端消息推送 SSE 是 Server-Sent Events 的简称&#xff0c; 是一种服务器端到客户端(浏览器)的单项消息推送。对应的浏览器端实现 Event Source 接口被制定为HTML5 的一部分。相比于 WebSocket&#xff0c;服务器端和客户端工作量都要小很多、简单很多&#xff0c…

[m1pro ] ssh: connect to host localhost port 22: Connection refused

在学习Hadoop 的时候&#xff0c;使用 ssh localhost 遇到以下问题 原因&#xff1a; 本地没有打开远程登录 解决办法&#xff1a;打开远程登录 成功结果

防御保护---防火墙的用户认证

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.用户认证概述 防火墙用户认证是一种安全措施&#xff0c;用于验证和授权网络用户的身份。它是防火墙的一部分&#xff0c;旨在确保只有经过身份验证的用户才能访问网络资源。 防火墙用户认证…

JDK1.8新特性(Day24)

Lambda表达式 介绍 Lambda表达式是一种没有名字的函数,也可称为闭包&#xff0c;是Java 8 发布的最重要新特性。本质上是一段匿名内部类&#xff0c;也可以是一段可以传递的代码。还有叫箭头函数的... 闭包 闭包就是能够读取其他函数内部变量的函数,比如在java中,方法内部的局…

智慧文旅:打造无缝旅游体验的关键

随着科技的快速发展和消费者需求的不断升级&#xff0c;旅游业正面临着前所未有的变革压力。智慧文旅作为数字化转型的重要领域&#xff0c;旨在通过智能化、数据化手段为游客提供更加优质、便捷、个性化的服务&#xff0c;打造无缝的旅游体验。本文将深入探讨智慧文旅在打造无…

第九节HarmonyOS 常用基础组件17-ScrollBar

1、描述 滚动条组件ScrollBar&#xff0c;用于配合可滚动组件使用&#xff0c;如List、Grid、Scroll。 2、接口 可包含子组件 ScrollBar(value:{scroller:Scroller, direction?: ScrollBarDirection, state?: BarState}) 3、参数 参数名 参数类型 必填 描述 scrolle…

R-YOLO

Abstract 提出了一个框架&#xff0c;名为R-YOLO&#xff0c;不需要在恶劣天气下进行注释。考虑到正常天气图像和不利天气图像之间的分布差距&#xff0c;我们的框架由图像翻译网络&#xff08;QTNet&#xff09;和特征校准网络&#xff08;FCNet&#xff09;组成&#xff0c;…