Python 网络爬虫:深入解析 Scrapy

        大家好,在当今数字化时代,获取和分析网络数据是许多项目的关键步骤。从市场竞争情报到学术研究,网络数据的重要性越来越被人们所认识和重视。然而,手动获取和处理大量的网络数据是一项繁琐且耗时的任务。幸运的是,Python 的 Scrapy 框架为我们提供了一种强大且高效的解决方案。

        Scrapy 是一个基于 Python 的开源网络爬虫框架,它能够帮助我们快速、高效地抓取和处理网络数据。无论是抓取网页内容、提取结构化数据还是进行数据清洗和分析,Scrapy 都是一种强大的工具。在接下来的内容中,我们将深入探讨 Scrapy 的各个方面,从安装和快速入门开始,逐步介绍其核心组件和高级功能。我们将探讨如何编写 Spider 来定义抓取规则,如何定义 Item 来提取数据,以及如何编写 Pipeline 来处理爬取到的数据。此外,我们还将介绍一些高级用法,如异步处理、用户代理和IP代理、分布式爬取等。

一、介绍

1、什么是 Scrapy?

        Scrapy 是一个基于 Python 的高级网络爬虫框架,用于快速、高效地抓取和处理网页数据。它提供了强大的功能和灵活的架构,使得开发者能够轻松构建和部署自己的网络爬虫。Scrapy 被广泛应用于数据挖掘、搜索引擎、市场分析、学术研究等领域。

2、Scrapy 的主要特点

Scrapy 框架具有许多强大的特点,使其成为首选的网络爬虫工具:

  • 高效性:Scrapy 采用异步处理和多线程机制,能够快速高效地抓取大量网页数据。
  • 灵活性:Scrapy 提供了丰富的配置选项和可扩展的架构,开发者可以根据自己的需求定制和扩展爬虫功能。
  • 智能调度:Scrapy 能够智能调度和管理爬取任务,支持优先级调度、并发控制、下载延迟等策略,确保爬虫的稳定性和效率。
  • 强大的选择器:Scrapy 提供了强大的选择器工具,如 XPath 和 CSS 选择器,方便开发者快速提取目标数据。
  • 数据处理管道:Scrapy 提供了数据处理管道机制,可以方便地对爬取到的数据进行处理、过滤和存储。
  • 分布式支持:Scrapy 支持分布式爬取,可以通过分布式架构提高爬虫的性能和稳定性。

3、安装方法和环境要求

(1)安装方法

Scrapy 可以通过 pip 工具进行安装。在命令行中执行以下命令即可安装最新版本的 Scrapy:

pip install scrapy

(2)环境要求

为了正常安装和运行 Scrapy,需要满足以下环境要求:

  • Python 版本:Scrapy 支持 Python 3.5 及以上版本。
  • 操作系统:Scrapy 可以在 Windows、Linux 和 macOS 等操作系统上运行。
  • 其他依赖:Scrapy 还依赖于一些第三方库,如 Twisted、lxml、pyOpenSSL 等。在安装 Scrapy 时,这些依赖会自动安装。

安装完成后,就可以开始使用 Scrapy 来开发自己的网络爬虫了。

二、快速入门

        在这一部分,将介绍如何快速入门 Scrapy,并通过简单的示例演示如何创建一个新的 Scrapy 项目、编写爬虫 Spider,并运行爬虫来获取网页数据。

1、创建一个新的 Scrapy 项目

        要创建一个新的 Scrapy 项目,可以使用命令行工具 scrapy 提供的 startproject 命令。假设我们要创建一个名为 myproject 的项目,执行以下命令:

scrapy startproject myproject

这将在当前目录下创建一个名为 myproject 的文件夹,其中包含了 Scrapy 项目的基本结构:

myproject/scrapy.cfgmyproject/__init__.pyitems.pymiddlewares.pypipelines.pysettings.pyspiders/__init__.py
  • scrapy.cfg:Scrapy 项目的配置文件。
  • myproject/:Scrapy 项目的 Python 包。
  • items.py:定义爬取的数据模型。
  • middlewares.py:定义中间件。
  • pipelines.py:定义数据处理管道。
  • settings.py:Scrapy 项目的设置文件。
  • spiders/:存放爬虫 Spider 的目录。

2、编写爬虫 Spider

        在 spiders/ 目录下,可以创建一个新的 Python 文件来编写爬虫 Spider。假设我们要编写一个简单的 Spider 来抓取某个网站的标题和链接,创建一个名为 example.py 的文件,内容如下:

import scrapyclass ExampleSpider(scrapy.Spider):name = 'example'start_urls = ['http://example.com']def parse(self, response):for article in response.css('article'):yield {'title': article.css('h2::text').get(),'link': article.css('a::attr(href)').get(),}

        在这个示例中,我们定义了一个名为 ExampleSpider 的 Spider,指定了它的名称为 'example',并指定了起始 URL 为 'http://example.com'。在 parse 方法中,我们使用 CSS 选择器提取了页面中所有的文章标题和链接,并使用 yield 返回抓取到的数据。

3、运行爬虫并查看结果

        要运行刚刚编写的 Spider,可以使用命令行工具 scrapy 提供的 crawl 命令。在项目根目录下执行以下命令:

cd myproject
scrapy crawl example

        这将会启动名为 'example' 的 Spider,并开始抓取数据。抓取完成后,爬取到的数据会默认打印到控制台上。也可以将数据保存到文件或者数据库中,具体可以在 Spider 中自行定义。

三、Scrapy 核心组件

        Scrapy 框架包含了多个核心组件,它们协同工作来完成网络爬虫的各个阶段任务。下面我们将逐一介绍这些核心组件及其用法:

1、Spider

(1)作用和用法:

        Spider 是 Scrapy 框架中最重要的组件之一,用于定义爬虫的行为和抓取规则。每个 Spider 负责从网页中提取数据,并将数据封装为 Item 对象。Spider 需要实现一个或多个爬取网页的方法,通常名为 parse

(2)编写 Spider 的步骤

编写 Spider 的步骤如下:

  1. 创建一个 Spider 类,继承自 scrapy.Spider
  2. 在 Spider 类中定义 name 属性,指定 Spider 的名称。
  3. 在 Spider 类中定义 start_urls 属性,指定起始 URL。
  4. 在 Spider 类中实现 parse 方法,用于解析网页内容并提取数据。

(3)示例

下面是一个简单的示例,展示了如何编写一个 Spider 来抓取网页的标题和链接:

import scrapyclass MySpider(scrapy.Spider):name = 'myspider'start_urls = ['http://example.com']def parse(self, response):# 提取网页中的标题和链接for article in response.css('article'):yield {'title': article.css('h2::text').get(),'link': article.css('a::attr(href)').get(),}

        在这个示例中,我们创建了一个名为 MySpider 的 Spider 类,指定了它的名称为 'myspider',并指定了起始 URL 为 'http://example.com'。在 parse 方法中,我们使用 CSS 选择器提取了页面中所有的文章标题和链接,并使用 yield 返回抓取到的数据。 

2、Item

(1)作用和用法:

        Item 是用来定义爬取到的数据的容器,类似于字典。通过定义 Item 类型,可以明确数据的结构,便于后续处理和存储。在 Spider 中提取到的数据可以封装为 Item 对象,然后交给 Pipeline 进行处理。

(2)定义 Item 的步骤

定义 Item 的步骤如下:

  1. 创建一个类,继承自 scrapy.Item
  2. 在类中定义数据字段,字段类型可以是 scrapy.Field 或其子类。

(3)示例

下面是一个简单的示例,展示了如何定义一个 Item 类来存储网页中的标题和链接:

import scrapyclass MyItem(scrapy.Item):title = scrapy.Field()link = scrapy.Field()

        在这个示例中,我们创建了一个名为 MyItem 的 Item 类,定义了两个字段 titlelink,分别用于存储网页中的标题和链接。这样定义后,我们在 Spider 中抓取到数据后,就可以将数据封装为 MyItem 对象,并交给 Pipeline 进行处理。 

3、Pipeline

(1)作用和用法:

        Pipeline 是用来处理爬取到的数据的组件。当 Spider 提取到数据后,数据会被交给 Pipeline 进行处理,可以进行数据清洗、过滤、验证、存储等操作。Pipeline 可以定义多个,按照优先级依次处理数据。

(2)编写 Pipeline 的步骤

编写 Pipeline 的步骤如下:

  1. 创建一个类,实现 process_item 方法。
  2. process_item 方法中对爬取到的数据进行处理,并返回处理后的数据或者抛出异常。

(3)示例

下面是一个简单的示例,展示了如何编写一个 Pipeline 来处理爬取到的数据并存储到文件中:

class MyPipeline(object):def process_item(self, item, spider):# 处理爬取到的数据,存储到文件中with open('data.txt', 'a', encoding='utf-8') as f:f.write(f"{item['title']}, {item['link']}\n")return item

        在这个示例中,我们创建了一个名为 MyPipeline 的 Pipeline 类,实现了 process_item 方法。在 process_item 方法中,我们对爬取到的数据进行处理,并将数据存储到文件 'data.txt' 中。最后,我们返回处理后的数据,以便后续的 Pipeline 继续处理或者返回给 Spider。 

4、Middleware

(1)作用和用法:

        Middleware 是 Scrapy 框架的中间件,用于处理请求和响应的过程。它可以在请求被 Spider 处理前和响应被 Spider 处理后对其进行预处理或后处理。Middleware 可以用于修改请求和响应、处理异常、实现代理和用户认证等功能。

(2)编写 Middleware 的步骤

编写 Middleware 的步骤如下:

  1. 创建一个类,实现 process_requestprocess_response 方法。
  2. process_request 方法中对请求进行预处理,然后返回处理后的请求对象。
  3. process_response 方法中对响应进行后处理,然后返回处理后的响应对象。

(3)示例

下面是一个简单的示例,展示了如何编写一个 Middleware 来实现请求和响应的日志记录:

class MyMiddleware(object):def process_request(self, request, spider):# 在请求被 Spider 处理前进行预处理print(f"Processing request: {request.url}")return requestdef process_response(self, request, response, spider):# 在响应被 Spider 处理后进行后处理print(f"Processing response: {response.url}")return response

        在这个示例中,我们创建了一个名为 MyMiddleware 的 Middleware 类,实现了 process_requestprocess_response 方法。在 process_request 方法中,我们打印了请求的 URL,在 process_response 方法中,我们打印了响应的 URL。通过这样的方式,我们可以记录请求和响应的信息,方便进行调试和监控。

5、完整示例

        下面是一个简单的示例,演示了如何使用 Scrapy 框架创建一个爬虫,爬取 Quotes to Scrape 网站上的名言,并将结果保存到 JSON 文件中。

import scrapy
from scrapy.crawler import CrawlerProcessclass QuotesSpider(scrapy.Spider):name = 'quotes'start_urls = ['http://quotes.toscrape.com']def parse(self, response):for quote in response.css('div.quote'):yield {'text': quote.css('span.text::text').get(),'author': quote.css('span small::text').get(),'tags': quote.css('div.tags a.tag::text').getall(),}next_page = response.css('li.next a::attr(href)').get()if next_page is not None:yield response.follow(next_page, self.parse)# 定义 Scrapy 爬虫的设置
custom_settings = {'FEEDS': {'quotes.json': {'format': 'json'}}, # 将结果保存到 quotes.json 文件中
}# 创建一个 CrawlerProcess 并运行我们的爬虫
process = CrawlerProcess(settings=custom_settings)
process.crawl(QuotesSpider)
process.start()

        运行上述代码,它将从 Quotes to Scrape 网站上抓取名言数据,并将结果保存到 quotes.json 文件中。

四、Scrapy 高级用法

        Scrapy 提供了许多高级功能和技巧,可以帮助你进一步优化和提升爬虫的效率和性能。在这一部分,我们将介绍 Scrapy 的三个高级用法:异步处理、用户代理和 IP 代理、以及分布式爬取。

1、异步处理

异步处理机制:

Scrapy 使用异步处理机制来提高爬取效率。异步处理允许多个操作同时进行,而不会阻塞其他操作。在 Scrapy 中,下载器、中间件和爬虫等组件都是基于 Twisted 框架实现的,利用 Twisted 的事件驱动模型实现了异步处理。

利用异步处理提升爬取效率:

要利用异步处理提升爬取效率,可以注意以下几点:

  • 使用异步请求:Scrapy 默认使用异步请求下载网页,可以同时下载多个网页,提高爬取效率。
  • 使用异步中间件:编写自定义的异步中间件,可以在请求发送和响应处理过程中执行异步操作,如请求重试、代理切换等。
  • 避免阻塞操作:在 Spider 中尽量避免执行阻塞操作,如文件 I/O、数据库查询等,以充分发挥异步处理的优势。

        在 Scrapy 中,默认已经实现了异步处理,但你也可以自定义异步中间件来执行一些异步操作。以下是一个简单的异步中间件示例,用于在请求发送前和响应处理后打印日志:

import scrapy
from twisted.internet.defer import Deferredclass AsyncMiddleware:def process_request(self, request, spider):# 在请求发送前执行异步操作d = Deferred()d.addCallback(self.print_log)d.callback(request)return ddef process_response(self, request, response, spider):# 在响应处理后执行异步操作d = Deferred()d.addCallback(self.print_log)d.callback(response)return ddef print_log(self, result):print("Async operation completed:", result)class MySpider(scrapy.Spider):name = 'example'start_urls = ['http://example.com']def parse(self, response):pass

2、用户代理和IP代理

设置用户代理和 IP 代理:

在进行网页抓取时,有些网站会根据请求的用户代理(User-Agent)和 IP 地址来识别爬虫并限制访问。为了规避这些限制,可以设置用户代理和 IP 代理。

常用的用户代理和 IP 代理获取方法:

  • 用户代理:可以在 Spider 中设置 USER_AGENT,也可以使用第三方的用户代理池服务,如 Fake User-Agent、fake-useragent 等。
  • IP 代理:可以使用公开的免费代理,也可以购买付费代理服务,如阿布云、快代理等。

        在 Scrapy 中设置用户代理和 IP 代理可以通过在 Spider 中设置请求头部信息来实现。以下是一个示例,使用随机的用户代理来发送请求:

import scrapy
from scrapy import Request
from fake_useragent import UserAgentclass MySpider(scrapy.Spider):name = 'example'start_urls = ['http://example.com']def parse(self, response):# 随机生成用户代理user_agent = UserAgent().random# 设置请求头部信息headers = {'User-Agent': user_agent}# 发送请求yield Request(url="http://example.com", headers=headers, callback=self.parse_page)def parse_page(self, response):pass

3、分布式爬取

分布式爬取功能:

Scrapy 支持分布式爬取,可以在多台机器上运行爬虫,并将抓取到的数据统一存储或处理。分布式爬取可以提高爬取速度和效率,同时也增加了系统的可扩展性和稳定性。

利用分布式爬取提高爬取速度和效率:

要利用分布式爬取提高爬取速度和效率,可以采取以下措施:

  • 使用分布式任务调度器:如 scrapy-redis、scrapy-cluster 等,用于在多台机器之间协调任务调度和数据交换。
  • 使用分布式存储和处理:将爬取到的数据存储在分布式数据库或对象存储中,如 MongoDB、Elasticsearch、Hadoop 等,以及使用分布式计算框架进行数据处理和分析。

        要实现分布式爬取,可以使用 Scrapy-Redis 组件。Scrapy-Redis 提供了分布式爬取的支持,可以通过 Redis 来协调多个爬虫节点的任务调度和数据交换。以下是一个简单的示例,展示了如何在 Scrapy-Redis 中配置和使用分布式爬取:

import scrapy
import scrapy_redisclass MySpider(scrapy.Spider):name = 'example'start_urls = ['http://example.com']def parse(self, response):pass# 配置 Scrapy-Redis
REDIS_URL = 'redis://localhost:6379'
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
ITEM_PIPELINES = {'scrapy_redis.pipelines.RedisPipeline': 300,
}# 配置 Redis 连接信息
REDIS_HOST = 'localhost'
REDIS_PORT = 6379

五、常见问题

1、如何处理反爬虫机制?

问题: 部分网站可能会设置反爬虫机制,如限制频繁请求、检测用户代理等,导致爬虫无法正常工作。

解答: 可以采取以下措施应对反爬虫机制:

  • 设置合理的下载延迟和并发量,避免频繁请求。
  • 使用随机的用户代理和 IP 代理,防止被网站识别为爬虫。
  • 使用验证码识别工具或人工识别验证码。
  • 分析网站的反爬虫策略,针对性地调整爬虫策略和参数。

2、如何处理网页内容解析错误?

问题: 在解析网页内容时,可能会遇到 HTML 结构变化、元素定位错误等问题,导致数据提取失败。

解答: 可以采取以下措施应对网页内容解析错误:

  • 使用更加精确的 CSS 选择器或 XPath 表达式来定位元素,避免因页面结构变化导致定位失败。
  • 编写容错处理逻辑,处理解析失败的情况,如设置默认值、捕获异常等。
  • 分析网页结构变化的原因,及时更新爬虫代码以适应新的页面结构。

3、如何处理数据存储和处理错误?

问题: 在数据存储和处理过程中,可能会遇到数据库连接错误、数据格式错误等问题,导致数据丢失或存储失败。

解答: 可以采取以下措施应对数据存储和处理错误:

  • 添加异常处理逻辑,捕获可能出现的异常并进行处理,如重新连接数据库、记录错误日志等。
  • 使用数据验证工具或库,对爬取到的数据进行验证和清洗,保证数据的完整性和准确性。
  • 使用分布式存储和处理方案,将数据存储在多个节点,提高系统的可靠性和稳定性。

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

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

相关文章

vue3 todolist 简单例子

vue3 简单的TodList 地址: https://gitee.com/cheng_yong_xu/vue3-composition-api-todo-app-my 效果 step-1 初始化项项目 我们不采用vue cli 搭建项目 直接将上图文件夹,复制到vscode编辑器,清空App.vue的内容 安装包 # 安装包 npm…

云原生架构案例分析_2.云原生技术助力某汽车公司数字化转型实践

名词解释: 互联网 在“互联网”模式下,我们仅仅把互联网看作是一种传播工具、传播手段、传播渠道和传播平台,对于互联网的应用大体上是在既有的运作逻辑的基础之上,把互联网作为延伸传媒影响力、价值和功能的一种延伸型工具&…

Linux基础1-基本指令1

1.Linux学习前言 Linux的学习非常重要,我们学习Linux的第一步是在电脑中搭建Linux环境。 对于没有搭建过的可以看这阿伟t的一篇文章 【Linux入门】Linux环境配置-CSDN博客 我的环境为XShell,运行的云服务器是阿里云 2.本章重点 1.显示当前目录下的所有文件…

针对大模型的上下文注入攻击

大型语言模型(LLMs)的开发和部署取得了显著进展。例如ChatGPT和Llama-2这样的LLMs,利用庞大的数据集和Transformer架构,能够产生连贯性、上下文准确性甚至具有创造性的文本。LLMs最初和本质上是为静态场景设计的,即输入…

Xilinx RFSOC 47DR 8收8发 信号处理板卡

系统资源如图所示:  FPGA采用XCZU47DR 1156芯片,PS端搭载一组64Bit DDR4,容量为4GB,最高支持速率:2400MT/s;  PS端挂载两片QSPI X4 FLASH;  PS支持一路NVME存储;  PS端挂载SD接口,用于存储程序&…

解决kettle界面右上角的connect消失——且使用admin登录不上Kettle资源库

一、问题描述 1.1、Kettle界面右上角的connect消失了 当我们配置Kettle界面的资源库(Other Repositories)内容后,Kettle界面右上角的connect消失了;如下图所示: 1.2、使用默认的账户【admin】和密码【admin】登录不上kettle资源库 当我们切换到我们配置的数据库使用超管账…

uniapp实现微信小程序调用云函数【vue3】

本人是从微信开发者工具写原生微信小程序一步一步走来,由于vue3框架的慢慢的步入前端市场,为了不被前端市场遗弃,果断从vue2开始步入vue3的学习,本人习惯在在HBuilder X写uniapp的项目,过去uniapp默认vue2框架&#xf…

注册北京个体工商户条件和办理时间

在北京这座充满活力的城市中,每天都有无数的创业者怀揣着梦想,踏上创业之路。然而,对于许多初次接触企业注册的人来说,往往对注册流程和时间感到困惑。特别是选择代理服务时,更希望了解一个大概的时间范围。那么&#…

【案例实操】银河麒麟桌面操作系统实例分享,V10SP1重启后网卡错乱解决方法

1.问题现象 8 个网口, 命名从 eth1 开始到 eth8。 目前在系统 grub 里面加了 net.ifnames0 biosdevname0 参数, 然后在 udev 规则中加了一条固定网卡和硬件 pci 设备号的规则文件。 最后在 rc.local 中加了两条重新安装网卡驱动的命令( rmmod…

Spring 中如何控制 Bean 的加载顺序?

如果你脱口而出说添加 Order 注解或者是实现 Ordered 接口,那么恭喜,你掉坑了。 一 Order 注解和 Ordered 接口 在 Spring 框架中,Order 是一个非常实用的元注解,它位于 spring-core 包下,主要用于控制某些特定上下文…

git基本使用——回退,撤销add,commit,合并分支

学习笔记 笔记中表格中的—— 表示需要回退的地方,也就是使用命令之后会改变的地方 网页软件分享 这是一个非常好用web端笔记画图软件,解决了typora画图不方便的问题

模板-初阶

引言: 在C,我们已经学过了函数重载,这使得同名函数具有多个功能。但是还有一种更省力的方法:采用模板。 本文主要介绍以下内容 1. 泛型编程 2. 函数模板 3. 类模板 1.泛型编程 在将这一部分之前,通过一个故事引…

mysql中EXPLAIN详解

大家好。众所周知,MySQL 查询优化器的各种基于成本和规则的优化会后生成一个所谓的执行计划,这个执行计划展示了接下来具体执行查询的方式。在日常工作过程中,我们可以使用EXPLAIN语句来查看某个查询语句的具体执行计划, 今天我们…

数据库索引的理解

目录 1.索引是什么,解决了什么问题 2.索引付出了什么代价 3.如何使用sql索引,有何注意事项 普通索引: 唯一索引: 主键索引(Primary Key Index): 删除索引: 创建主键索引的基本语法: 4.索引背后的数据结构 1.索…

数据结构严蔚敏版精简版-绪论

1.基本概念和术语 下列概念和术语将在以后各章节中多次出现,本节先对这些概念和术语赋予确定的含义。 数据(Data):数据是客观事物的符号表示,是所有能输入到计算机中并被计算机程序处理的符号 的总称。 数据元素(DataElement):…

基于STM32的水库预警系统的Proteus仿真

文章目录 一、水库预警系统1.题目要求2.思路2.1 OLED显示汉字2.2 水质传感器等等2.3 步进电机2.4 驱动水泵 3.仿真图3.1 未仿真时3.2 开始仿真,OLED开始显示3.3 提高水位,开启阀门和预警3.4 通过按键增大水位阈值,取消报警 4.仿真程序4.1 程序…

轻松拿捏C语言——【文件操作】

🥰欢迎关注 轻松拿捏C语言系列,来和 小哇 一起进步!✊ 🎉创作不易,请多多支持🎉 🌈感谢大家的阅读、点赞、收藏和关注💕 🌹如有问题,欢迎指正 目录 &#x1f…

谨以此文章记录我的蓝桥杯备赛过程

以国优秀结束了蓝桥杯cb组 鄙人来自电信学院,非科班出身,在寒假,大约2024年2月份,跟着黑马程序员将c基础语法学完了,因为过年,事情较多,没在学了。 最初就是抱着拿省三的态度去打这个比赛的&a…

C语言之旅:探索单链表

目录 一、前言 二、实现链表的功能: 打印 创建节点 尾插 尾删 头插 头删 查找 在指定位置之前插入数据 指定位置删除 在指定位置之后插入数据 打印 销毁 三、全部源码: 四、结语 一、前言 链表是一个强大且基础的数据结构。对于很多初…

禁用手机连接 - Win11

问题 Win11系统自带手机连接软件,会在后台自启,不适用于全部的手机型号,而且常规方法无法卸载。甚至任务管理器中,此软件的后台进程高达76个,如下图。下文以Win11系统为例,介绍如何禁用手机连接。 解决方…