初步搭建并使用Scrapy框架

目录

目标

版本

实战

搭建框架

获取图片链接、书名、价格

通过管道下载数据

通过多条管道下载数据

下载多页数据


目标

        掌握Scrapy框架的搭建及使用,本文以爬取当当网魔幻小说为案例做演示。


版本

        Scrapy 2.12.0


实战

搭建框架

第一步:在D:\pytharm_workspace位置创建爬虫Scrapy项目。通过cmd在该目录执行Scrapy创建项目命令。dangdang是我的项目名称。

scrapy startproject dangdang

第二步:进入项目目录,并创建爬虫类。其中magic_novels是我自定义的爬虫程序名称,permit.mee.gov.cn表示要爬取的网站域名。

第三步:注释在settings文件中掉OBOTSTXT_OBEY协议。

#ROBOTSTXT_OBEY = True

第四步:打开Pycharm控制台,进入项目目录。设置start_urls为我们要爬取的首页。parse表示项目启动后会自动请求start_urls中的URL。所以我们在parse方法中调试输出,并运行项目。

import scrapyclass MagicNovelsSpider(scrapy.Spider):name = "magic_novels"allowed_domains = ["category.dangdang.com"]start_urls = ["https://category.dangdang.com/cp01.03.40.00.00.00.html"]def parse(self, response):print(response.url)print(response.text)

 scrapy crawl magic_novels

第五步:此时会打印很多的无用信息,我们可以在settings.py文件中设置日志级别。再次启动项目后会发现页面干净了很多。

LOG_LEVEL = "WARNING"
scrapy crawl magic_novels
注意:如果多次请求导致可能会导致缓存出现,请使用以下命令:
scrapy crawl magic_novels --set HTTPCACHE_ENABLED=False

获取图片链接、书名、价格

第一步:通过xpath爬取价格、图片、书名,我们先来打印调试。此时发现图片的链接不对,思考是否是懒加载的一个反扒策略。

    def parse(self, response):'''图片的链接:src=//ul[@id='component_59']/li//img/@src图片的名称:alt=//ul[@id='component_59']/li//img/@alt图书的价格:price=//ul[@id='component_59']/li//p[@class='price']/span考虑到所有的数据都来源于//ul[@id='component_59']/li,所以我们可以复用li对象。'''li_list = response.xpath("//ul[@id='component_59']/li")for li in li_list:print(f'图片的链接:src={li.xpath(".//img/@src").extract_first()}')print(f'图片的名称:alt={li.xpath(".//img/@alt").extract_first()}')print(f'图书的价格:price={li.xpath(".//p[@class='price']/span[1]/text()").extract_first()}')print("\n")

第二步: 刷新页面,在浏览器检查中查看第一个和最后一个,发现图片链接的初始接收属性并不是src,而是data-original,src是加载以后才代替data-original的。

第三步:修改src获取的方法,并再次运行项目。发现除了第一个图书的src为None,其他src都正常获取了。猜测:是不是第一个图书打开时没有使用懒加载。

第四步: 通过调试发现,确实如刚才的猜想一般,第一个图书的src没有使用懒加载。修改代码后再次调试,发现可以获取到第一个图书的链接。

    def parse(self, response):'''图片的链接:src=//ul[@id='component_59']/li//img/@src图片的名称:alt=//ul[@id='component_59']/li//img/@alt图书的价格:price=//ul[@id='component_59']/li//p[@class='price']/span考虑到所有的数据都来源于//ul[@id='component_59']/li,所以我们可以复用li对象。'''li_list = response.xpath("//ul[@id='component_59']/li")for i , li in enumerate(li_list):print(f'第{i+1}本书。')src = li.xpath(".//img/@data-original").get()if src is None:src = li.xpath(".//img/@src").get()alt = li.xpath(".//img/@alt").get()price = li.xpath(".//p[@class='price']/span[1]/text()").get()print(f'图片的链接:src={src}')print(f'图片的名称:alt={alt}')print(f'图书的价格:price={price}')print("\n")


通过管道下载数据

第一步:打开items.py文件,配置字段。

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapyclass DangdangItem(scrapy.Item):# 图片src = scrapy.Field()# 书名name = scrapy.Field()# 价格price = scrapy.Field()

第二步:将item类导入到爬虫程序。

import scrapyfrom dangdang.items import DangdangItemclass MagicNovelsSpider(scrapy.Spider):name = "magic_novels"allowed_domains = ["category.dangdang.com"]start_urls = ["https://category.dangdang.com/cp01.03.40.00.00.00.html"]def parse(self, response):'''图片的链接:src=//ul[@id='component_59']/li//img/@src图书的名称:alt=//ul[@id='component_59']/li//img/@alt图书的价格:price=//ul[@id='component_59']/li//p[@class='price']/span考虑到所有的数据都来源于//ul[@id='component_59']/li,所以我们可以复用li对象。'''li_list = response.xpath("//ul[@id='component_59']/li")for i , li in enumerate(li_list):print(f'第{i+1}本书。')src = li.xpath(".//img/@data-original").get()if src is None:src = li.xpath(".//img/@src").get()alt = li.xpath(".//img/@alt").get()price = li.xpath(".//p[@class='price']/span[1]/text()").get()print(f'图片的链接:src={src}')print(f'图书的名称:alt={alt}')print(f'图书的价格:price={price}')print("\n")#该对象要通过管道去下载,通过yield可以在每次获得book后立刻返回book给管道。book=DangdangItem(src=src, alt=alt, price=price);yield book

第三步:在settings.py中开启管道配置。管道可以有很多个并且有优先级,300是默认值,值越大优先级越小。

ITEM_PIPELINES = {"dangdang.pipelines.DangdangPipeline": 300,
}

第四步:来到pipelines.py文件,其中process_item方法中的item就是我们刚才在爬虫程序配置的boot对象。我们可以打印测试效果。

class DangdangPipeline:def process_item(self, item, spider):print(type(item))print(str(item))return item
scrapy crawl magic_novels

思考:我们通过process_item可以获取到数据,但是每次循环获取数据再重新打开文件、写入数据,关闭文件明显不符合开发规范。

第五步:在pipelines.py文件中配置open_spider和close_spider方法,分别表示在爬虫程序执行前执行的方法和在爬虫程序执行之后执行的方法。我们可以打印日志测试。

class DangdangPipeline:#在爬虫文件开始之前就执行的方法def open_spider(self, spider):print("++++")def process_item(self, item, spider):print(type(item))print(str(item))return item#在爬虫文件执行之后再执行的方法def close_spider(self, spider):print("----")
scrapy crawl magic_novels

第六步: 下载JSON数据。

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import json# useful for handling different item types with a single interface
from itemadapter import ItemAdapterclass DangdangPipeline:#在爬虫文件开始之前就执行的方法def open_spider(self, spider):self.fp=open("book.json","w",encoding="utf-8")self.fp.write("[")def process_item(self, item, spider):line = json.dumps(dict(item), ensure_ascii=False) + ",\n"self.fp.write(line)return item#在爬虫文件执行之后再执行的方法def close_spider(self, spider):# 删除最后一个多余的逗号,并关闭 JSON 数组self.fp.seek(self.fp.tell() - 3, 0)  self.fp.write("\n]")self.fp.close()
scrapy crawl magic_novels

 


通过多条管道下载数据

第一步:在pipelines.py文件中定义新的管道类。

#下载图片
class DangdangDownloadImgPipeline:# 在爬虫文件开始之前就执行的方法def open_spider(self, spider):passdef process_item(self, item, spider):print(item.get('src'))url="http:"+item.get('src')filename='C:/Users/Administrator/Desktop/test/'+sanitize_filename(item.get("alt"))+'.jpg'urllib.request.urlretrieve(url=url,filename=filename)return item# 在爬虫文件执行之后再执行的方法def close_spider(self, spider):passdef sanitize_filename(filename):"""替换 Windows 文件名中不合法的字符为下划线。"""# 定义 Windows 文件名不允许的字符invalid_chars = r'[\\/:*?"<>|]'# 使用正则表达式将非法字符替换为下划线return re.sub(invalid_chars, '_', filename)

第二步:在settings.py中定义该管道类的优先级。

ITEM_PIPELINES = {"dangdang.pipelines.DangdangPipeline": 300,"dangdang.pipelines.DangdangDownloadImgPipeline": 300,
}

第三步:执行下载操作,可以看到JSON数据和图片都下载成功了。

scrapy crawl magic_novels


下载多页数据

思考:目前我们只是下载了第一页的数据,能否通过配置页码下载多个页面的数据呢?

第一步:去页面点击下一页,发现链接都差不多,区别在于pg后面的跟的页码。

https://category.dangdang.com/pg2-cp01.03.40.00.00.00.html
https://category.dangdang.com/pg3-cp01.03.40.00.00.00.html

第二步:在爬虫程序中,设置基础的url和页码,页码初始化为第一页。

class MagicNovelsSpider(scrapy.Spider):name = "magic_novels"allowed_domains = ["category.dangdang.com"]start_urls = ["https://category.dangdang.com/cp01.03.40.00.00.00.html"]base_url="https://category.dangdang.com/pg"page_num=1;

第三步:在parse方法中递归请求当当网,每次请求都将url的页码改变。注意:递归逻辑写在循环之外。

import scrapyfrom dangdang.items import DangdangItemclass MagicNovelsSpider(scrapy.Spider):name = "magic_novels"allowed_domains = ["category.dangdang.com"]start_urls = ["https://category.dangdang.com/cp01.03.40.00.00.00.html"]base_url="https://category.dangdang.com/pg"page_num=1;def parse(self, response):'''图片的链接:src=//ul[@id='component_59']/li//img/@src图书的名称:alt=//ul[@id='component_59']/li//img/@alt图书的价格:price=//ul[@id='component_59']/li//p[@class='price']/span考虑到所有的数据都来源于//ul[@id='component_59']/li,所以我们可以复用li对象。'''li_list = response.xpath("//ul[@id='component_59']/li")for i , li in enumerate(li_list):print(f'第{i+1}本书。')src = li.xpath(".//img/@data-original").get()if src is None:src = li.xpath(".//img/@src").get()alt = li.xpath(".//img/@alt").get()price = li.xpath(".//p[@class='price']/span[1]/text()").get()print(f'图片的链接:src={src}')print(f'图书的名称:alt={alt}')print(f'图书的价格:price={price}')print("\n")#该对象要通过管道去下载,通过yield可以在每次获得book后立刻返回book给管道。book=DangdangItem(src=src, alt=alt, price=price);yield bookif self.page_num<3:self.page_num+=1url=self.base_url+str(self.page_num)+"-cp01.03.40.00.00.00.html";#GET请求yield scrapy.Request(url=url, callback=self.parse)

第四步:运行项目。发现可以正常下载前三页的数据。

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

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

相关文章

Python网络自动化运维---用户交互模块

文章目录 目录 文章目录 前言 实验环境准备 一.input函数 代码分段解析 二.getpass模块 前言 在前面的SSH模块章节中&#xff0c;我们都是将提供SSH服务的设备的账户/密码直接写入到python代码中&#xff0c;这样很容易导致账户/密码泄露&#xff0c;而使用Python中的用户交…

通过frm和ibd文件恢复mysql数据

1.提取所有的文件名并查找出以frm结尾的 dir /t /b >1.txt 2.要准备的软件 1.mysql-utilities-1.6.5-winx64.msi 2.vcredist_x64.exe(c 2013) 3.利用frm生成sql文件 mysqlfrm --serverroot:123456localhost:3306 --port3308 D:\phpstudy_pro\Extensions\MySQL5.7.26\da…

notepad++下载安装及使用笔记

文章目录 可以打开多大的文件可以打开多大的文件和内存设置有关吗&#xff0c;如何设置? TODO 如果打不开太大的文件 拆分为200M的肯定可以打开Find All in CurrentDocument(在当前文档中找到所有) 下载从百度网盘下载从官网下载 主要为了本地看大日志方便&#xff0c;例如几百…

【面试题】java基础概念

以下是关于这道面试题的回答&#xff0c;包括JDK中一些相关概念的区别以及JIT的原理&#xff1a; JDK中相关概念区别 JDK、JRE和JVM JDK&#xff08;Java Development Kit&#xff09;&#xff1a;是Java开发工具包&#xff0c;它包含了JRE和一系列开发工具。JDK提供了编译、…

Linux内核中的InfiniBand核心驱动:verbs.c分析

InfiniBand(IB)是一种高性能、低延迟的网络互连技术,广泛应用于高性能计算(HPC)、数据中心和云计算等领域。Linux内核中的InfiniBand子系统通过提供一组核心API(称为Verbs API)来支持InfiniBand设备的操作。drivers/infiniband/core/verbs.c是InfiniBand核心驱动的重要组…

《CPython Internals》阅读笔记:p329-p335

《CPython Internals》学习第 16天&#xff0c;p329-p335 总结&#xff0c;总计 7 页。 一、技术总结 1.debugging p331, There are two types of debugger, console and visual——作者将 debugger分为两类&#xff1a;(1)console&#xff1a;lldb(MAC系统使用), GDB(Linux…

【2024年 CSDN博客之星】我的2024年创作之旅:从C语言到人工智能,个人成长与突破的全景回顾

我的2024年创作之旅&#xff1a;从C语言到人工智能&#xff0c;个人成长与突破的全景回顾 引言 回望2024年&#xff0c;我不仅收获了技术上的成长&#xff0c;更收获了来自CSDN平台上无数粉丝、朋友以及网友们的支持与鼓励。在这条创作之路上&#xff0c;CSDN不仅是我展示技术成…

【程序化广告】相关技术(RTB竞价原理、Cookie映射流程、数据统计原理、程序化创意、防作弊方法)

上一篇介绍了【程序化广告】广告投放流程/漏斗/要素/策略/指标&#xff0c;本篇介绍一下程序化广告所使用到的相关技术&#xff0c;包括RTB竞价原理、Cookie映射流程、数据统计原理、程序化创意、防作弊方法等。 1. RTB竞价原理 1&#xff09;竞价逻辑 用户开启电脑&#xf…

软件测试入门—用例设计中的场景图和状态迁移图

在软件测试领域&#xff0c;用例设计是一项至关重要的工作&#xff0c;它直接关系到软件质量的高低。而场景图和状态迁移图作为用例设计中的两种有效工具&#xff0c;能够帮助测试人员更全面、系统地设计测试用例。下面我们就来深入了解一下这两种图。 一、场景图 场景图主要…

数据表中的数据查询

文章目录 一、概述二、简单查询1.列出表中所有字段2.“*”符号表示所有字段3.查询指定字段数据4.DISTINCT查询 三、IN查询四、BETWEEN ADN查询1.符合范围的数据记录查询2.不符合范围的数据记录查询 五、LIKE模糊查询六、对查询结果排序七、简单分组查询1.统计数量2.统计计算平均…

第11章:Python TDD实现货币类加法运算初步

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…

前端Vue2项目使用md编辑器

项目中有一个需求&#xff0c;要在前端给用户展示内容&#xff0c;内容有 AI 生成的&#xff0c;返回来的是 md 格式&#xff0c;所以需要给用户展示 md 格式&#xff0c;并且管理端也可以编辑这个 md 格式的文档。 使用组件库 v-md-editor。 https://code-farmer-i.github.i…

Windows系统提示RunDLL PcaWallpaperAppDetect错误修复方法

最近&#xff0c;Win11 24H2预览版和Win10 LTSC 2025功能更新偶尔会触发RunDLL错误弹窗 具体表现为 //英文提示 Error in C:\WINDOWS\system32\PcaSvc.dll Missing entry: PcaWallpaperAppDetect//中文提示 C:\WINDOWS\system32\PcaSvc.dll出错 丢失条目:PcaWallpaperAppDe…

【计算机视觉】人脸识别

一、简介 人脸识别是将图像或者视频帧中的人脸与数据库中的人脸进行对比&#xff0c;判断输入人脸是否与数据库中的某一张人脸匹配&#xff0c;即判断输入人脸是谁或者判断输入人脸是否是数据库中的某个人。 人脸识别属于1&#xff1a;N的比对&#xff0c;输入人脸身份是1&…

光谱相机在智能冰箱的应用原理与优势

食品新鲜度检测 详细可点击查看汇能感知团队实验报告&#xff1a;高光谱成像技术检测食物新鲜度 检测原理&#xff1a;不同新鲜程度的食品&#xff0c;其化学成分和结构会有所不同&#xff0c;在光谱下的反射、吸收等特性也存在差异。例如新鲜肉类和蔬菜中的水分、蛋白质、叶…

Dangerzone:免费的危险的文件转换安全程序

我们知道很多杀毒软件会将很多文件视作恶意程序&#xff0c;尤其是带宏病毒的DOC文件&#xff0c;直接删除难免会带来不必要的麻烦&#xff0c;那么推荐一款免费的危险的文件转换安全程序&#xff1a;Dangerzone 。它可以检查各种可能有危险的文件并将其转换为安全版本&#xf…

销售线索管理的价值以及主要方法

销售线索管理的价值体现在&#xff1a;提高销售效率、优化客户体验、提升转化率、支持数据驱动决策。其中&#xff0c;提高销售效率尤为关键。通过系统化的线索管理&#xff0c;销售团队能够更快地识别和跟进潜在客户&#xff0c;从而缩短销售周期。自动化的线索评分和分配减少…

手写SOCKET进行HTTP通信

网络基础 我们电脑主板上都内置了多种网卡&#xff0c;一般主要有以下几类&#xff1a; 虚拟网卡&#xff08;loopback&#xff09; 注意&#xff0c;它是虚拟的&#xff0c;并不是物理网卡&#xff0c;也被称为是本地环回地址(或接口)&#xff0c;一般将127.0.0.1作为本地环回…

在 C++ 中实现调试日志输出

在 C 编程中&#xff0c;调试日志对于定位问题和优化代码至关重要。有效的调试日志不仅能帮助我们快速定位错误&#xff0c;还能提供有关程序运行状态的有价值的信息。本文将介绍几种常用的调试日志输出方法&#xff0c;并教你如何在日志中添加时间戳。 1. 使用 #ifdef _DEBUG…

MFC程序设计(二)基于对话框编程

从现在开始&#xff0c;我们将以基于对话框的MFC应用程序来讲解MFC应用 向导生成基于对话框MFC应用程序 对话框是一种特殊类型的窗口&#xff0c;绝大多数Windows程序都通过对话框与用户进行交互。在Visual C中&#xff0c;对话框既可以单独组成一个简单的应用程序&#xff0…