Python框架Scrapy

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Python框架Scrapy

一、简介

1 Scrapy的定义

Scrapy 是一个用 Python 编写的开源网络爬虫框架。

2 Scrapy的特点

  1. 基于 Twisted 异步网络库,实现高效地异步操作。
  2. 支持自动抓取数据,自动处理数据。
  3. 支持分布式爬取和多线程、多进程的高效爬取。
  4. 可以自定义条件进行 URL 过滤。
  5. 支持动态网站的数据爬取。

3 Scrapy的优点

  1. 组件化设计,方便维护和扩展。
  2. 可以通过插件的形式和其他库结合使用。
  3. 自带命令行工具,方便调试和操作。
  4. 支持多种数据存储方式。
  5. 代码简洁,易于上手。

二、Scrapy的模块结构与工作流程

1 Scrapy的模块结构

  • Scrapy Engine(引擎):整个框架的核心,负责调度和控制整个爬虫流程。
  • Scheduler(调度器):调度器,负责安排爬取任务的先后顺序。
  • Downloader(下载器):下载器,负责下载网页内容和其他资源文件。
  • Spiders(爬虫):爬虫,负责页面解析和数据项的抽取。
  • Item Pipeline(数据管道):数据管道,负责数据的处理和存储。
  • Middlewares(中间件):中间件,负责整个爬虫流程中的各种处理逻辑。

2 Scrapy的工作流程

  1. 爬虫从 start_urls 开始爬取,并将 URL 添加到调度器中。
    ```python
    import scrapy

class MySpider(scrapy.Spider):

name = 'example'

start_urls = ['http://example.com']

def parse(self, response):
    # 解析响应
    pass

2. **调度器从等待队列中取出一个爬取请求,并把它传递给下载器。**
```python
class MySpider(scrapy.Spider):

    name = 'example'

    start_urls = ['http://example.com']

    def parse(self, response):
        url = 'http://example.com/page1'  # 爬取的网址
        yield scrapy.Request(url, callback=self.parse_page1)  # 构造请求,添加至队列中

    def parse_page1(self, response):
        # 解析响应
        pass
  1. 下载器下载请求中的网页,并将响应交给爬虫。

    class MySpider(scrapy.Spider):
    
     name = 'example'
    
     start_urls = ['http://example.com']
    
     def parse(self, response):
         url = 'http://example.com/page1'  # 爬取的网址
         yield scrapy.Request(url, callback=self.parse_page1)  # 构造请求,添加至队列中
    
     def parse_page1(self, response):
         html = response.body  # 获取响应的 HTML 代码
         pass
    
  2. 爬虫解析响应内容,筛选数据并生成 Item 对象。

    class MySpider(scrapy.Spider):
    
     name = 'example'
    
     start_urls = ['http://example.com']
    
     def parse(self, response):
         url = 'http://example.com/page1'  # 爬取的网址
         yield scrapy.Request(url, callback=self.parse_page1)  # 构造请求,添加至队列中
    
     def parse_page1(self, response):
         item = {
         }
         item['title'] = response.css("title::text").get()  # 从响应数据中获取文章标题
         yield item  # 返回项目
    
  3. Item Pipeline 处理 Item 对象,将数据存储到指定的地方。
    ```python
    class MyPipeline(object):

    def process_item(self, item, spider):

     # 处理 item
     return item
    

settings.py

ITEM_PIPELINES = {'myproject.pipelines.MyPipeline': 300}


6. **爬虫结束后,Scrapy Engine 关闭。**

## 3 Scrapy的数据流

Scrapy 的数据流可以用以下 4 个步骤来描述:

1. **开始爬取页面**
```python
class MySpider(scrapy.Spider):

    name = 'example'

    start_urls = ['http://example.com']

    def parse(self, response):
        # 开始爬取
        pass
  1. 页面下载

    class MySpider(scrapy.Spider):
    
     name = 'example'
    
     start_urls = ['http://example.com']
    
     def parse(self, response):
         url = 'http://example.com/page1'  # 爬取的网址
         yield scrapy.Request(url, callback=self.parse_page1)  # 构造请求,添加至队列中
    
  2. 页面解析和数据抽取

    class MySpider(scrapy.Spider):
    
     name = 'example'
    
     start_urls = ['http://example.com']
    
     def parse(self, response):
         item = {
         }
         item['title'] = response.css("title::text").get()  # 从响应数据中获取文章标题
         yield item  # 返回项目
    
  3. 数据保存

    class MyPipeline(object):
    
     def process_item(self, item, spider):
         # 处理 item
         with open('data.json', 'w') as f:
             json.dump(item, f)
         return item
    

通过以上的介绍和示例对 Scrapy 已经有了一个基本的了解,如果想要更深入的了解和使用可以参考 Scrapy 的官方文档或者尝试写一些简单的 Scrapy 程序,感受一下其中的乐趣。

三、Scrapy的主要组件

1 Scrapy Engine

Scrapy Engine是整个框架的核心,它负责控制和调度整个爬虫流程,包括处理整个流程中的各种事件和数据,以及在最终完成爬虫工作时通知其他所有组件。

Scrapy Engine也是其他所有组件的接口,因此其他组件必须与Scrapy Engine交互,以便在整个爬虫流程中发挥其功能。

class Engine(object):
    def __int__(self):
        self.spider = None
        self.scheduler = None
        self.downloader = None
        self.pipeline = None
    def start(self):
        # 启动整个流程,包括 Scheduler、Downloader、Spider 和 Pipeline 组件
        pass

2 Scheduler组件

Scheduler组件是用于管理Scrapy Engine和其他所有组件之间的调度流程的主要组件。它的工作是将爬取请求安排好按顺序逐个执行,通过按照设定的规则为每个爬取请求选择最优的下载器,并且确保经过多次爬取请求的重试和处理后,将结果存储到Item Pipeline中。

class Scheduler(object):
    def __init__(self):
        self.queue = []
    def push(self, request):
        # 将 request 加入队列等待下载器的下载
        pass
    def pop(self):
        # 从队列中获取下一个要下载的 request,并返回
        pass
    def next_request(self):
        # 得到下一个要下载的 request 并调用 Downloader 组件
        pass

3 Downloader组件

Downloader组件是用于处理爬取请求的主要组件。它从Web服务器上下载HTML、XML等页面和图片、视频等资源文件,并将下载好的资源交给Spider组件解析得到数据结果集。

Downloader组件通过异步I/O通道进行访问互联网获取相应网页,并区分不同的请求,处理cookie、User-Agent和代理IP,还能在不同的线程和进程中处理请求,提高爬取和处理数据的效率。

class Downloader(object):
    def __init__(self):
        self.session = requests.Session()
    def fetch(self, request):
        # 根据 request 获取数据,并返回 Response 对象
        pass
    def process_request(self, request):
        # 处理 Request 对象
        pass

4 Spider组件

Spider组件是用于处理爬取请求以及解析和抽取数据的主要组件。它接收Downloader组件下载好的资源和响应,并解析出所需的数据,将其封装到Item对象中,然后再传递给Item Pipeline进行处理。

一个Spider组件属于某个项目,并且设计Spider组件时需要模拟这个项目的数据清晰结构和相应爬取规则。其工作方式通常是,首先通过scrapy.Spider类的方法解析给定的起始url,然后跟进响应的url递归请求直到完成爬取任务。在这个过程中,还可以使用各种的解析器和正则表达式,以获得需要的数据。

class Spider(object):
    def process_response(self, request, response):
        # 处理 Response 对象 
        pass

5 Item Pipeline组件

Item Pipeline组件是Scrapy中一个非常重要的组件,它是数据处理管道的核心,负责处理和持久化Item对象中的数据。Item Pipeline组件可以为数据处理提供方便的机制,并且可以允许多个数据流通过管道,并进行高级数据处理。

Item Pipeline组件的处理方式可以分为三个步骤:接收完整的Item对象,进行数据处理和管理以及发送处理后的Item对象。

class Pipeline(object):
    def process_item(self, item):
        # 处理 Item 对象 
        pass

四、Scrapy的数据流

Scrapy的数据流包括Request/Response Objects,Item Objects,Spiders和Item Pipeline,具体的数据流程如下:

1 Request/Response Objects

爬虫代码中用户定义Request对象,Scrapy引擎将Request发送到Scheduler组件。Scheduler在一定时间内安排请求的执行和重试,然后将最终结果返回给Scrapy Engine。在Scrapy Engine中,Response对象包含着Scrapy从Web服务器上获得的所有HTML、XML或JSON代码等响应内容。当Scrapy Engine获得这些响应并分配给正确的Spider处理时,Response对象就成为Request对象的响应,再由Spider解析响应对象并抽取出所需数据,最终将数据保存到Item对象中。

2 Item Objects

在Scrapy Engine中,Item对象是处理数据的容器。Item Pipeline将Item对象中的数据处理和保存下来,如XML或JSON格式的数据存储到数据库中,或将处理后得到的数据渲染到模板上,生成可以阅读或打印的本地文件。Scrapy中支持多个Item Pipeline,它们通过一系列的操作和管道将数据从Spider组件传递到其他数据处理组件中。

class Item(object):
    def __init__(self):
        self.data = {
   }
    def __setitem__(self, key, value):
        # 设置数据项
        self.data[key] = value
    def __getitem__(self, key):
        # 获取数据项
        return self.data[key]

3 Spiders

Spiders就是写爬取规则的地方,它包含了处理爬取请求和处理响应的所有必要逻辑代码。Spiders生成至少一个Item对象,该对象封装数据并且发送到Item Pipeline中。以Python代码为例,Spiders使用XPath或BeautifulSoup等HTML解析器将Response对象分析为字典或列表的形式,并从中抽取所需数据。

class Spider(object):
    def parse(self, response):
        # 解析 Response 对象获取数据并返回 Item 对象
        pass
    def start_requests(self):
        # 发起 HTTP 请求或将请求加入 Scheduler 中等待处理?
        pass

4 Item Pipeline

Item Pipeline负责处理和管理从Spider组件中创建的Item对象,以及进行数据持久化、数据格式转换和数据清洗等操作。数据处理管道将Item对象传递到另一个处理器,最终将处理后的数据存储在数据库等其他某种存储设备中。Item Pipeline的有效性在于可以提供一种机制,即使从多个并行流中处理数据,也可以按照你的预期顺序操作,而不会出现任何错误的顺序或数据问题。

class Pipeline(object):
    def process_item(self, item):
        # 处理 Item 对象 
        pass

五、Scrapy的常用命令

1 创建Scrapy项目

要创建一个新的Scrapy项目可以在命令行中使用 "scrapy startproject" 命令。如下所示,对于一个名为 "myproject" 的项目,我们可以按照以下方式创建它:

$ scrapy startproject myproject

2 创建Spider

要创建一个新的Spider可以使用命令 "scrapy genspider"。如下所示,为了创建一个名为 "mySpider" 的Spider并以 "mydomain.com" 为起始地址,可以按照以下方式创建它:

$ scrapy genspider mySpider mydomain.com

3 运行Spider

要运行Spider可以在项目主目录下使用 "scrapy crawl" 命令。如下所示,对于名为 "mySpider" 的Spider,我们可以按照以下方式运行它:

$ scrapy crawl mySpider

4 查看Spider数据

Scrapy提供了多种方便的方式来查看Spider的数据,包括输出到命令行、保存到文件、存储到数据库等。在Spider类中,可以使用 "logging"类将数据输出到命令行或日志文件。

import logging

class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['http://www.example.com']

    def parse(self, response):
        # 解析响应并得到数据
        item = {
   'title': response.css('title::text').get()}
        # 将数据输出到命令行和日志文件
        self.logger.info(item)
        logging.debug(item)

六、Scrapy常见问题解决方法

1 Scrapy运行慢

Scrapy的运行速度是由众多因素决定的,但可能会与以下因素有关:

  1. 网络连接速度慢或Web服务器响应速度慢。
  2. Spider在解析和处理页面数据时,采用了复杂的算法,导致爬取过程缓慢。
  3. 爬虫程序在运行时占用大量的系统资源,如、内存或处理器带宽等。

为了尽可能地优化Scrapy运行速度,可以采取以下措施:

  1. 优化网络连接速度:使用更快的Internet连接或使用Web服务器的CDN等加速技术。
  2. 优化Spider,避免在处理数据时采用过于复杂的算法。尽可能选择更快和更轻量级的算法。
  3. 调整Scrapy的配置,以便更充分优化资源使用,这包括适当地配置线程、进程和内存限制等。

2 Scrapy在多线程上的表现

Scrapy是一种基于协程的异步框架,因此它对于多线程的支持不同于其他的爬虫框架。Scrapy通过异步执行HTTP请求来提高爬取性能,并通过并发递归实现了爬虫的高效率。

Scrapy支持线程池,可以使用 Python 的 threading 模块和 Queue 模块实现多线程爬取。如果需要在Scrapy中使用多线程,可以考虑适当的调整并发请求限制、设置队列容量,避免资源冲突等。

3 Scrapy在分布式上的表现

Scrapy本身支持分布式爬虫,但需要自己手动实现。一般来说,可以使用分布式队列、RPC等技术来实现Scrapy的数据共享。

为了更好地运用Scrapy可以考虑以下措施:

  1. 使用分布式的队列,如RabbitMQ等,并在所有节点上安装Scrapy,并将请求分发到不同的节点上。
  2. 使用RPC或Web服务来实现Scrapy节点之间的通信,以及处理共享的数据等。
  3. 对于稳定性或性能方面的要求比较高的应用,可以使用一些分布式框架,如Hadoop等,并使用Scrapy进行数据爬取,最终将数据存储在分布式存储系统中。

七、Scrapy的适用场景

Scrapy是现今最流行的网络爬虫框架之一它具有高效、可扩展性强、配置简单等优点。下面是Scrapy适用的场景

1. 数据挖掘

Scrapy可以在网络上帮助用户收集和分析数据。例如,可以使用Scrapy抓取并分析股票价格的数据,检索市场上的产品价格和销售情况。同时Scrapy还能帮助将这些数据存储在本地数据库或云服务中,以便进一步的数据挖掘。

2. 搜索引擎优化

Scrapy可以抓取网站有关的信息以便帮助网站优化。例如,可以使用Scrapy抓取并分析关键词的搜索排名情况,并对网站进行相应的优化操作。

3. 自动化测试

Scrapy可以在自动化测试期间模拟网页的行为,并检测应用程序中的异常行为。例如,可以使用Scrapy模拟用户在网站上的操作,以便检测应用当前的测试状态。同时,由于Scrapy具有高度可扩展的测试架构,因此用户可以使用Python编写自己的测试脚本,以满足项目的不同需求。

4. 其他方面的数据采集

Scrapy可应用于各种类型的数据采集项目,如新闻报道、竞争对手产品信息抓取、政府部门和学术研究数据收集等。由于用户可以灵活定义Scrapy爬虫的规则, Scrapy具有适应性很强的特点。

八、Scrapy的应用案例

以下三个应用案例展示了Scrapy在不同场景下的表现

1. 电影网 Top 250 的抓取

电影Top 250是一个电影爱好者喜欢访问的网站。该网站提供了不同类型电影的信息和评分,可以使用Scrapy 抓取整个网站的数据,存储到本地数据库或者进行在线分析处理。下面是用Python实现的相应代码:

    # 导入Scrapy类库
    import scrapy
    # 建立Spider类
    class DoubanSpider(scrapy.Spider):
        # 定义Spider名称和起始URL地址
        name = 'aaa'
        start_urls = ['https://movie.aaa.com/top250']
        # 定义parse回调函数
        def parse(self, response):
            # 解析响应内容并爬取所需数据
            pass

2. 求职网职位的抓取

求职网提供各类IT职位信息。使用Scrapy可以轻松地抓取所有职位发布信息。下面是用Python实现的相应代码:

    # 导入Scrapy类库
    import scrapy
    # 建立Spider类
    class LagouSpider(scrapy.Spider):
        # 定义Spider名称和起始URL地址
        name = 'qiuzhi'
        start_urls = ['https://www.qiuzhi.com/']
        # 定义parse回调函数
        def parse(self, response):
            # 解析响应内容并爬取所需数据
            pass

3. 古诗文网的抓取

古诗文网是一家专门汇总古代诗词、曲文、散文等文学作品的网站,使用Scrapy 可以轻松抓取相关的文学作品并存储到本地数据库。 下面是用Python实现的相应代码:

    # 导入Scrapy类库
    import scrapy
    # 建立Spider类
    class GushiwenSpider(scrapy.Spider):
        # 定义Spider名称和起始URL地址
        name = 'gushiwen'
        start_urls = ['https://www.gushiwen.org/']
        # 定义parse回调函数
        def parse(self, response):
            # 解析响应内容并爬取所需数据
            pass

九、Scrapy的发展方向

在过去的几年Scrapy已经成为了网络爬虫领域里最受欢迎的框架之一。然而不同的应用场景和趋势需要不断优化和改进Scrapy,以下是Scrapy的发展方向:

1. 异步网络库的支持

随着互联网的发展和网络的不断扩容,采取异步编程方式可以极大地提高程序性能。因此Scrapy的下一个发展方向之一是支持异步网络库。针对大规模的请求,Scrapy需要与高效异步网络库(如Tornado, asyncio, Twisted等)进行集成,以便在运行爬虫时能够更好地处理异步请求,大幅提高程序效率。

2. 爬虫数据的机器学习

现如今机器学习在许多领域里都有广泛应用。对于Scrapy来说,采用机器学习技术可以更准确地分析和提取数据。这可以通过对Scrapy爬虫所获取的内容进行训练,从而使爬虫程序自动的识别和提取更具体的信息和数据。从而更快速、更准确地完成数据采集任务。

3. 容错机制的加强

在网络爬虫的实践中由于网络环境的多变及网站采用反爬技术等原因,Scrapy的稳定性有时候还需要进一步加强。一个强大的容错机制可以帮助Scrapy更好的应对这种网络环境下的不稳定因素。针对这个问题,Scrapy社区可以推动开发更多强韧的容错机制,以便程序可以更好的应对各种异常情况。

4. 集成数据可视化工具

Scrapy可以采集大量的数据但如果没有一个清晰的分析和展示平台,数据就无法得到合理的利用。因此,将数据可视化工具集成进来成为了Scrapy的又一个发展方向。通过集成可视化工具(如Matplotlib, Plotly, D3等),Scrapy可以直接在程序内部实现数据可视化的功能,帮助用户更好地理解和分析爬取到的数据。

十、小结回顾

随着互联网的发展网络爬虫技术也越来越成熟。Scrapy作为其中的代表框架,具有极大的优势和广泛的应用。在不断完善和优化Scrapy的过程中相信Scrapy将能够更好地满足各行各业的需求,成为网络爬虫技术的代表和领导者。

目录
相关文章
|
16天前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
60 6
|
16天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
103 45
|
10天前
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
46 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
17天前
|
数据采集 前端开发 中间件
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第26天】Python是一种强大的编程语言,在数据抓取和网络爬虫领域应用广泛。Scrapy作为高效灵活的爬虫框架,为开发者提供了强大的工具集。本文通过实战案例,详细解析Scrapy框架的应用与技巧,并附上示例代码。文章介绍了Scrapy的基本概念、创建项目、编写简单爬虫、高级特性和技巧等内容。
40 4
|
17天前
|
安全 数据库 开发者
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第26天】本文详细介绍了如何在Django框架下进行全栈开发,包括环境安装与配置、创建项目和应用、定义模型类、运行数据库迁移、创建视图和URL映射、编写模板以及启动开发服务器等步骤,并通过示例代码展示了具体实现过程。
29 2
|
17天前
|
网络协议 物联网 API
Python网络编程:Twisted框架的异步IO处理与实战
【10月更文挑战第26天】Python 是一门功能强大且易于学习的编程语言,Twisted 框架以其事件驱动和异步IO处理能力,在网络编程领域独树一帜。本文深入探讨 Twisted 的异步IO机制,并通过实战示例展示其强大功能。示例包括创建简单HTTP服务器,展示如何高效处理大量并发连接。
39 1
|
20天前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
Python Web框架比较:Django vs Flask vs Pyramid
28 1
|
29天前
|
JSON 搜索推荐 API
Python的web框架有哪些?小项目比较推荐哪个?
【10月更文挑战第15天】Python的web框架有哪些?小项目比较推荐哪个?
48 1
|
1月前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
Python Web框架比较:Django vs Flask vs Pyramid
24 4
|
8天前
|
安全 API 网络架构
Python中哪个框架最适合做API?
本文介绍了Python生态系统中几个流行的API框架,包括Flask、FastAPI、Django Rest Framework(DRF)、Falcon和Tornado。每个框架都有其独特的优势和适用场景。Flask轻量灵活,适合小型项目;FastAPI高性能且自动生成文档,适合需要高吞吐量的API;DRF功能强大,适合复杂应用;Falcon高性能低延迟,适合快速API开发;Tornado异步非阻塞,适合高并发场景。文章通过示例代码和优缺点分析,帮助开发者根据项目需求选择合适的框架。
27 0