网络爬虫框架Scrapy的入门使用

Scrapy的入门使用

  • Scrapy
    • 概述
    • 引擎(Engine)
    • 调度器(Scheduler)
    • 下载器(Downloader)
    • Spider
    • Item Pipeline
  • 基本使用
    • 安装scrapy
    • 创建项目
    • 定义Item数据模型对象
    • 创建爬虫(Spider)
    • 管道pipeline来保存数据
    • 启动爬虫
  • 其他
    • 解析函数对象
    • 实现多请求
  • scrapy终端(Scrapy shell)
    • 启动终端
    • 可用Scrapy对象
    • 快捷命令

Scrapy

概述

Scrapy是一个用Python编写的开源网络爬虫框架,专门设计用于快速、高效地提取网站数据。它提供了一整套工具和库,可以帮助开发人员创建和管理网络爬虫,用于抓取特定网站的数据并进行处理。

英文文档:https://docs.scrapy.org/en/latest/

GitHub:https://github.com/scrapy/scrapy

中文文档:https://scrapy-chs.readthedocs.io/zh_CN/latest/

Scrapy是一个基于Python的Web爬虫框架,由多个组件组成,包括了引擎(Engine)、调度器(Scheduler)、下载器(Downloader)、Spider、Item Pipeline等。

引擎(Engine)

引擎是Scrapy的核心组件之一,负责调度和协调各个组件的工作。它接收Spider返回的初始请求,并将其传递给调度器,再由调度器根据一定的策略进行调度,最终将请求发送给下载器进行下载。在下载器将响应内容返回后,引擎将调用Spider的回调函数进行处理,再将处理后的数据交给Item Pipeline进行处理。

调度器(Scheduler)

调度器负责对Spider的请求进行调度,决定请求的顺序和时间。它维护了一个请求队列,并根据一定的调度策略,将请求传递给下载器进行下载。在下载完成后,调度器将下载器返回的响应对象传递给Spider进行处理。

下载器(Downloader)

下载器负责从互联网上下载页面和资源。它接收调度器传递的请求对象,并根据请求中的URL和请求头信息进行下载。下载器可以通过设置代理、Cookies和请求头等信息,模拟浏览器的行为,避免被服务器拒绝访问。在下载完成后,下载器将响应对象返回给调度器。

Spider

Spider是用户编写的爬虫代码,定义了如何爬取和处理页面数据。它通过yield关键字返回请求对象或者Item对象,并可以定义一个或多个回调函数,在下载器返回响应对象后进行解析和处理。Spider可以通过设置start_urls或者start_requests方法返回一个或多个初始请求对象。

Item Pipeline

Item Pipeline负责处理Spider返回的Item对象,可以对数据进行过滤、清理、验证等操作。它将Item对象传递给一系列的管道处理器,每个管道处理器可以对Item对象进行一些处理操作,然后将处理后的Item对象传递给下一个管道处理器。在最后一个管道处理器处理完成后,Item Pipeline将Item对象输出到文件或者数据库中。

基本使用

安装scrapy

pip install scrapy

查看帮助命令

> scrapy --help
Scrapy 2.8.0 - no active projectUsage:scrapy <command> [options] [args]Available commands:bench         Run quick benchmark testfetch         Fetch a URL using the Scrapy downloadergenspider     Generate new spider using pre-defined templatesrunspider     Run a self-contained spider (without creating a project)settings      Get settings valuesshell         Interactive scraping consolestartproject  Create new projectversion       Print Scrapy versionview          Open URL in browser, as seen by Scrapy[ more ]      More commands available when run from project directoryUse "scrapy <command> -h" to see more info about a command

创建项目

scrapy startproject 项目名称

会在当前目录下创建一个名为project_name的目录,包含了Scrapy项目的基本结构。
在这里插入图片描述
项目目录结构:

scrapy.cfg: 项目的配置文件demo: 项目的python模块,之后将在此加入代码demo/spiders/: 爬虫组件目录demo/items.py: 定义数据模型demo/middlewares.py: 自定义中间件demo/pipelines.py: 自定义管道,保存数据demo/settings.py: 爬虫配置信息

定义Item数据模型对象

Item是保存爬取到的数据的容器。通过创建一个 scrapy.Item 类, 并且定义类型为scrapy.Field的类属性来定义一个Item

定义item即提前规划好哪些字段需要抓,防止在爬取数据过程中写错。

配合注释一起可以清晰的知道要抓取哪些字段,

数据模型对象类定义以后需要在爬虫中导入并且实例化,使用方法和使用字典相同

在items.py中定义模型对象,定义要提取的字段:

import scrapyclass DemoItem(scrapy.Item):# 标题title = scrapy.Field()# 数量count = scrapy.Field()

在这里插入图片描述

创建爬虫(Spider)

Spider是编写用于从单个网站(或者一些网站)爬取数据的类。其包含一个用于下载的初始URL,如何跟进网页中的链接以及如何分析页面中的内容, 提取生成 item 的方法。

创建一个Spider,必须继承scrapy.Spider类, 且定义一些属性、方法:

name:

用于区别Spider。 该名字必须是唯一的,不可以为不同的Spider设定相同的名字。

start_urls:

包含Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。

parse() :

parse()是spider的一个方法。 被调用时,每个初始URL完成下载后生成的Response对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。

demo/spiders目录下创建demospider.py文件,需要定义一个Spider类,继承自scrapy.Spider类,并重写start_requests()parse()方法。

import scrapyfrom demo.items import DemoItem# 继承自爬虫类
class DemospiderSpider(scrapy.Spider):# 定义爬虫名称name = "demospider"# 设置允许爬取的范围allowed_domains = ["www.runoob.com"]# 设置开始爬取的请求地址start_urls = ["https://www.runoob.com/"]# 实现解析函数,提取数据或者提取URL,并提交给引擎def parse(self, response):# scrapy的response对象可以直接进行xpathlist = response.xpath('/html/body/div[4]/div/div[2]/div/h2/text()').extract()print("--------------------------------")index = 1for title in list:div = "div[" + str(index) + "]"index = index + 1count = response.xpath('/html/body/div[4]/div/div[2]/' + div + '/a/h4/text()').extract()item = DemoItem()item['title'] = titleitem['count'] = len(count)# 提交数据给引擎# yield能够传递的对象只能是:BaseItem, Request, dict, Noneyield item

使用命令方式可以快速创建一个爬虫编写的基本结构

cd 项目目录scrapy genspider 爬虫名称 允许域名>scrapy genspider demospider www.runoob.com
Created spider 'demospider' using template 'basic' in module:demo.spiders.demospider

在这里插入图片描述

管道pipeline来保存数据

数据在被抓取后,被发送到管道,接着进行管道操作,比如:

清理 HTML 数据验证抓取的数据(检查项目是否包含某些字段)检查重复项(并删除它们)将抓取的项目存储在数据库中

在运行爬虫时添加 -o参考可以将数导出

scrapy crawl 爬虫名称 -o 导出文件

在pipelines.py文件中创建DemoPipeline管道类,打印爬虫的parse() 方法提取的数据

class DemoPipeline:# 爬虫文件中提取数据的方法每yield一次item,就会运行一次def process_item(self, item, spider):print("title: {} , count: {}".format(item['title'], item['count']))return item

在这里插入图片描述

完整管道实现如下:

# 1.在pipelines.py中编写管道实现# 2.定义管道类
class DemoPipeline:# 3.必须实现process_item(self,item,spider),在管道接收数据对象时回调,用于接收和处理每个数据对象def process_item(self, item, spider):print("title: {} , count: {}".format(item['title'], item['count']))return item# 4.可选实现def open_spider(self, spider):print("爬虫启动时回调,用于初始化操作")def close_spider(self, spider):print("爬虫关闭时回调,用于释放操作")

接着在settings.py中开启管道

配置项中键为使用的管道类,参数的值是一个权重,越小越优先执行

ITEM_PIPELINES = {"demo.pipelines.DemoPipeline":1
}

注意事项:

在管道实现函数中process_item必须有返回值,传递给下一个管道多管道实现时可以通过类型判断或爬虫名称判断区分存储的数据

启动爬虫

在命令行中,进入目录,并输入以下命令,运行Spider:

scrapy crawl 爬虫名称scrapy crawl demospider

控制台打印了爬虫提取数据日志与管道保存数据日志,如下所示:

--------------------------------
title:  HTML / CSS , count: 9
2023-02-22 14:07:26 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.runoob.com/>
{'count': 9, 'title': ' HTML / CSS'}
title:  JavaScript , count: 18
2023-02-22 14:07:26 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.runoob.com/>
{'count': 18, 'title': ' JavaScript'}
title:  服务端 , count: 26
2023-02-22 14:07:26 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.runoob.com/>

其他

解析函数对象

response对象

response响应对象封装从互联网上返回的响应,具有如下常用属性

response.url:当前响应的url地址response.request.url:当前响应对应的请求的url地址response.headers:响应头response.requests.headers:当前响应的请求头response.body:响应体,也就是html代码,byte类型response.status:响应状态码

Selector对象

Selector对象封装数据操作的对象

xpath:可以使用 xpath 提取数据,返回 SelectorList 对象css:可以使用 css 样式选择器提取数据,返回 SelectorList 对象extract:从selector对象中提取内容

SelectorList对象

返回 Selector 对象的合集

extract_first :取列表中第一个元素的内容,如果元素不存在返回 Noneextract :提取列表中selector对象中所有内容

提交数据给引擎

使用关键词 yield,在爬虫组件的解析函数中提交数据给引擎

提交数据类型:BaseItem、Request、dict、None

def parse(self,response):...item = {}item["data"] = "数据"yield item

实现多请求

构造Request对象,继续发送请求,从而实现多请求

scrapy.Request构建方式

scrapy.Request(url[,callback,method="GET",headers,body,cookies,meta,dont_filter=False])

注意:中括号里的参数为可选参数,具体意思如下:

callback: 表示当前的url的响应交给哪个函数去处理method:指定POST或GET请求headers:接收一个字典,其中不包括cookiescookies:接收一个字典,专门放置cookiesbody:接收json字符串,为POST的数据,发送payload_post请求时使用meta: 实现数据在不同的解析函数中传递,meta默认带有部分数据,比如下载延迟,请求深度等dont_filter: 默认会过滤请求的url地址,即请求过的url地址不会继续被请求,对需要重复请求的url地址可以把它设置为Turemeta的作用:meta可以实现数据在不同的解析函数中的传递

meta参数的使用

利用meta参数在不同的解析函数中传递数据

def parse(self,response):...yield scrapy.Request(detail_url, callback=self.parse_detail,meta={"item":item})...def parse_detail(self,response):# 获取传入的itemitem = resposne.meta["item"]

使用关键词 yield,提交请求给引擎

    # 实现解析函数,提取数据或者提取URL,并提交给引擎def parse(self, response):for title in response.xpath('//title').getall():item = DemoItem()item['title'] = titleyield itemfor href in response.xpath('//a/@href').getall():yield scrapy.Request(response.urljoin(href), self.parse)

scrapy终端(Scrapy shell)

Scrapy终端是一个交互终端,在未启动spider的情况下尝试及调试爬取代码,如用来测试XPath或CSS表达式

启动终端

scrapy shellscrapy shell 爬取地址scrapy shell www.runoob.com

可用Scrapy对象

Scrapy终端根据下载的页面会自动创建一些方便使用的对象

[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x00000114BB2603A0>
[s]   item       {}
[s]   request    <GET http://www.runoob.com>
[s]   response   <200 https://www.runoob.com/>
[s]   settings   <scrapy.settings.Settings object at 0x00000114BB260940>
[s]   spider     <DemospiderSpider 'demospider' at 0x114bb6f6dc0>
[s] Useful shortcuts:
[s]   fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s]   fetch(req)                  Fetch a scrapy.Request and update local objects
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser

快捷命令

shelp() - 打印可用对象及快捷命令的帮助列表
fetch(request_or_url) - 根据给定的请求(request)或URL获取一个新的response,并更新相关的对象
view(response) - 在本机的浏览器打开给定的response
>>> fetch(request)
2023-02-22 15:52:11 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (302) to <GET https://www.runoob.com/> from <GET http://www.runoob.com>
2023-02-22 15:52:11 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.runoob.com/> (referer: None)>>> view(response)
True

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

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

相关文章

cuda python课程中“使用 Numba 的 CUDA Python 的自定义核函数和内存管理“一个大坑

总觉得自己的算法没问题&#xff0c;最终还是测试结果不符。 错误出现在一个很顺眼的位置。 解决方案 在最终测验阶段有一个看起来没问题不需要任何修改的Cell&#xff0c;就是这一句&#xff0c;看起来没什么毛病 d_histogram_out cuda.device_array_like(histogram_out)需…

Java代码混淆技术在应用程序保护中的关键作用与应用

摘要 本文探讨了代码混淆在保护Java代码安全性和知识产权方面的重要意义。通过混淆技术&#xff0c;可以有效防止代码被反编译、逆向工程或恶意篡改&#xff0c;提高代码的安全性。常见的Java代码混淆工具如IPAGuard、Allatori、DashO、Zelix KlassMaster和yGuard等&#xff0…

【数据分析面试】3.编写数据选取函数(Python)

题目 给定了一个名为 students_df 的学生数据表格 nameagefavorite_colorgradeTim Voss19red91Nicole Johnson20yellow95Elsa Williams21green82John James20blue75Catherine Jones23green93 编写一个名为 grades_colors 的函数&#xff0c;以选择仅当学生喜欢的颜色是绿色或…

YOLOv5-小知识记录(三)

0. 写在前面 本篇介绍SPP模块、FPN模块模块&#xff0c;主要也是对YOLOv5的内容的补充&#xff1a; Yolo系列算法-理论部分-YOLOv4-CSDN博客 Yolo系列算法-理论部分-YOLOv5-CSDN博客 上一篇&#xff1a; YOLOv5-小知识记录(二)-CSDN博客 1. SPP模块 Spatial Pyramid Pooling…

探索数据库--------------mysql主从复制和读写分离

目录 前言 为什么要主从复制&#xff1f; 主从复制谁复制谁&#xff1f; 数据放在什么地方&#xff1f; 一、mysql支持的复制类型 1.1STATEMENT&#xff1a;基于语句的复制 1.2ROW&#xff1a;基于行的复制 1.3MIXED&#xff1a;混合类型的复制 二、主从复制的工作过程 三个重…

地物波谱库共享网站汇总

ENVI自5.2版本重新梳理了原有的标准波谱库&#xff0c;新增一些物质波谱&#xff0c;在ENVI5.6中存放在…\Harris\ENVI56\ resource\speclib&#xff0c;分别存放在四个文件夹中&#xff0c;储存为ENVI波谱库格式&#xff0c;有两个文件组成&#xff1a;.sli和.hdr。 ENVI保留…

2014年认证杯SPSSPRO杯数学建模B题(第二阶段)位图的处理算法全过程文档及程序

2014年认证杯SPSSPRO杯数学建模 B题 位图的处理算法 原题再现&#xff1a; 图形&#xff08;或图像&#xff09;在计算机里主要有两种存储和表示方法。矢量图是使用点、直线或多边形等基于数学方程的几何对象来描述图形&#xff0c;位图则使用像素来描述图像。一般来说&#…

|行业洞察·有色金属|《2000年以来各国黄金储备分析:金砖国家增持一有望持续助推金价中枢抬升》

报告内容的详细解读&#xff1a; 1. 全球央行黄金储备趋势 2011年以来&#xff0c;全球央行持续增加黄金储备&#xff0c;年均增持超过1000吨&#xff0c;成为黄金需求的重要一极。截至2023年&#xff0c;央行黄金储备占比不足5%的国家数量占比达到45%&#xff0c;而美国、德…

AI面试工具:为你的招聘需求选择正确的解决方案

如果你是一名招聘经理&#xff0c;那么考虑到市场上有多种AI面试工具&#xff0c;你完全有理由感到困惑。在这种情况下&#xff0c;人们通常会选择谷歌上排名靠前的单向视频面试工具&#xff0c;这都要归功于SEO。但我们不希望你随波逐流&#xff0c;在投资了数万元的招聘工具后…

day56 动态规划part13

300. 最长递增子序列 中等 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2,7] 是数组 [0,3,1,6,2,2,…

云原生架构(微服务、容器云、DevOps、不可变基础设施、声明式API、Serverless、Service Mesh)

前言 读完本文&#xff0c;你将对云原生下的核心概念微服务、容器云、DevOps、Immutable Infrastructure、Declarative-API、Serverless、Service Mesh 等有一个相对详细的了解&#xff0c;帮助你快速掌握云原生的核心和要点。 因题主资源有限, 这里会选用部分云服务商的组件进…

vant checkbox 复选框 样式改写

修改前 修改后 基于 vant&#xff1a; 4.8.3 unocss: 0.53.4 <van-checkbox-group v-model"query.zczb" shape"square" class"text-16 w-100% flex flex-wrap"><template v-for"item in registerCapitalOption"><v…