为了账号安全,请及时绑定邮箱和手机立即绑定

Scrapy学习:初学者必备教程

标签:
Python 爬虫
概述

Scrapy学习涵盖了从安装到项目部署的全过程,介绍了Scrapy的安装方法、项目结构和基本概念。文章还详细讲解了如何编写和使用Spider,以及高级技巧如中间件的定制和异常处理。

Scrapy简介与安装
Scrapy是什么

Scrapy 是一个用于抓取网站数据并提取结构化信息的 Python 库。它主要用于构建 Web 爬虫,能够快速地抓取数据并解析数据。Scrapy 通常用于数据挖掘、信息处理和存储,以及从网站收集数据等任务。Scrapy 的设计目标是将网络爬虫的编写变得简单且可扩展。

Scrapy的特点与优势

Scrapy 有以下几个显著的特点和优势:

  1. 异步爬取:Scrapy 使用异步 I/O 实现了高效的爬取速度,可以在短时间内处理大量请求。
  2. 强大的选择机制:Scrapy 提供了 XPath 和 CSS 选择器来解析 HTML 和 XML 代码,使得数据提取变得容易。
  3. 灵活的数据提取:Scrapy 通过定义 Item 和自定义提取规则来方便地获取所需数据。
  4. 可扩展性:Scrapy 的模块化设计使得扩展和自定义变得更加简单,可以方便地添加中间件、管道等组件。
  5. 稳健性:Scrapy 支持处理大量数据和高并发请求,能够避免被目标网站检测到并被封禁。
Scrapy的安装方法

Scrapy 可以通过 pip 包管理工具进行安装。以下是具体的安装步骤:

  1. 打开命令行工具(如 Windows 的命令提示符、macOS 或 Linux 的终端)。
  2. 使用以下命令安装 Scrapy:
pip install scrapy

此命令会安装 Scrapy 以及其依赖库。

创建第一个Scrapy项目

创建一个新的 Scrapy 项目需要执行以下步骤:

  1. 打开命令行工具。
  2. 转到你希望创建项目的工作目录。
  3. 执行以下命令来创建一个新的 Scrapy 项目(假设项目名为 myproject):
scrapy startproject myproject

该项目结构将如下:

myproject/
    scrapy.cfg          # 项目配置文件
    myproject/
        __init__.py     # 空白的 Python 包初始化文件
        items.py        # 定义项目中所有 Item 类的文件
        middlewares.py  # 定义中间件类的文件
        pipelines.py    # 定义 Pipeline 类的文件
        settings.py     # 项目的设置文件
        spiders/        # 存放所有 Spider 文件的目录
            __init__.py # 空白的 Python 包初始化文件
  1. spiders 目录下创建一个新的 Spider 类文件,例如 my_spider.py,并在其中定义一个简单的 Spider:
# myproject/spiders/my_spider.py
import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'  # Spider 名称
    start_urls = [
        'http://example.com/',
    ]

    def parse(self, response):
        # 解析响应内容
        self.log('Visited %s' % response.url)
  1. 运行新创建的 Spider:
cd myproject
scrapy crawl myspider

这将启动 Scrapy 并运行 myspider Spider,开始抓取 start_urls 中定义的 URL。

Scrapy项目结构与基本概念
Scrapy项目的文件结构

Scrapy 项目的目录结构如下:

  • scrapy.cfg:项目配置文件,用于设置 Scrapy 版本等信息。
  • myproject:项目的主目录,包括以下文件和文件夹:
    • __init__.py:空白的 Python 包初始化文件。
    • items.py:用于定义所有要抓取的数据结构。
    • pipelines.py:实现数据处理和保存的 Pipeline。
    • settings.py:设置 Scrapy 的全局配置。
    • spiders/:存放所有 Spider 文件的目录。
    • middlewares.py:用于定义中间件类的文件。
Scrapy的基本概念:Item,Spider,Pipeline等

Item

Item 是 Scrapy 中用来存储抓取数据的容器。它类似于 Python 字典,但更加严格,确保数据的一致性和规范性。在 items.py 文件中定义 Item 类:

# myproject/items.py
import scrapy

class MyprojectItem(scrapy.Item):
    title = scrapy.Field()
    url = scrapy.Field()
    content = scrapy.Field()

Item 类中定义了抓取数据的字段,例如 titleurlcontent。这些字段是 scrapy.Field 类型,用于存储数据。

Spider

Spider 是 Scrapy 中用于定义爬虫逻辑的类。一个 Spider 可以包含多个方法,如 start_requests()parse()。Spider 的主要功能是定义要抓取的 URL 和数据提取规则。例如:

# myproject/spiders/example_spider.py
import scrapy

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

    def parse(self, response):
        for item in response.css('div.item'):
            yield {
                'title': item.css('a::text').get(),
                'url': item.css('a::attr(href)').get(),
            }

在这个例子中,parse 方法使用 CSS 选择器提取数据。

Pipeline

Pipeline 是 Scrapy 中用于后处理抓取数据的机制。它负责对抓取的数据进行清洗、验证、持久化等操作。在 pipelines.py 文件中定义 Pipeline 类:

# myproject/pipelines.py
class MyprojectPipeline:
    def process_item(self, item, spider):
        # 对 item 数据进行处理
        return item

process_item() 方法用于处理传入的 Item 数据。

解释Scrapy的工作流程

Scrapy 的工作流程可以概括为以下几个步骤:

  1. 启动:通过执行 scrapy crawl <spider_name> 命令启动一个 Spider。
  2. 发送请求:Spider 中的 start_requests() 方法定义了初始 URL,然后 Scrapy 使用这些 URL 发送请求。
  3. 接收响应:Scrapy 发送请求后,会接收到响应。
  4. 解析数据:解析器(通常是 parse() 方法)解析响应内容,并从中提取数据。
  5. 生成 Item:解析方法生成并返回 Item 类的实例。
  6. 数据处理:Item 通过 Pipeline 进行处理,数据可以被清洗、验证或保存。
  7. 存储数据:处理过后,数据可以被保存到数据库或其他存储介质。
编写简单的Spider

以下是一个简单的 Spider 示例,用于抓取网站上的文章标题和链接:

# myproject/spiders/example_spider.py
import scrapy

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

    def parse(self, response):
        for article in response.css('div.post'):
            title = article.css('h2 a::text').get()
            url = article.css('h2 a::attr(href)').get()
            yield {
                'title': title,
                'url': url,
            }

此 Spider 定义了一个 parse() 方法,该方法使用 CSS 选择器提取文章标题和链接,并生成 Item

Scrapy Spider详解
编写和使用Spider

Spider 的基本结构包括以下几个部分:

  1. name:Spider 的名称,用于唯一标识 Spider。
  2. start_urls:包含初始 URL 的列表,用于启动爬取过程。
  3. parse 方法:解析响应内容并从中提取数据的方法。
# myproject/spiders/example_spider.py
import scrapy

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

    def parse(self, response):
        # 解析响应内容并提取数据
        for article in response.css('div.post'):
            title = article.css('h2 a::text').get()
            url = article.css('h2 a::attr(href)').get()
            yield {
                'title': title,
                'url': url,
            }
解析HTML页面

Scrapy 提供了两种主要的方法来解析 HTML 代码:XPath 和 CSS。

XPath

XPath 是一种在 XML 文档中查找节点的语言。Scrapy 使用 XPath 语法来定位和提取数据:

import scrapy

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

    def parse(self, response):
        # 使用 XPath 提取节点
        for article in response.xpath('//div[@class="post"]'):
            title = article.xpath('.//h2/a/text()').get()
            url = article.xpath('.//h2/a/@href').get()
            yield {
                'title': title,
                'url': url,
            }

CSS

CSS 选择器在 Scrapy 中用于选择 HTML 元素。CSS 选择器通常比 XPath 更具可读性,并且适用于简单的选择任务:

import scrapy

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

    def parse(self, response):
        # 使用 CSS 选择器提取节点
        for article in response.css('div.post'):
            title = article.css('h2 a::text').get()
            url = article.css('h2 a::attr(href)').get()
            yield {
                'title': title,
                'url': url,
            }
提取数据与追加请求

提取数据

Scrapy 提供了 extract()get() 方法来提取数据。extract() 方法返回一个列表,而 get() 方法返回单个值。

import scrapy

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

    def parse(self, response):
        titles = response.css('h1.title').extract()
        for title in titles:
            yield {'title': title}

追加请求

可以通过生成新的 Request 对象来追加请求。追加请求通常用于处理分页、递归调用等情况。

import scrapy

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

    def parse(self, response):
        next_page = response.css('a.next::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

        for item in response.css('div.post'):
            title = item.css('h2 a::text').get()
            url = item.css('h2 a::attr(href)').get()
            yield {
                'title': title,
                'url': url,
            }

在这个例子中,parse() 方法通过 response.follow() 方法生成新的请求,并传递回调函数 parse

Scrapy高级技巧
使用中间件定制Scrapy行为

Scrapy 中间件是一系列钩子函数,允许你拦截和修改请求和响应。中间件用于扩展 Scrapy 功能,例如处理登录、添加头信息等。

定义中间件

中间件的定义通常在 settings.py 文件中:

# myproject/settings.py
DOWNLOADER_MIDDLEWARES = {
    'myproject.middlewares.MyCustomMiddleware': 543,
}

中间件类定义在 middlewares.py 文件中:

# myproject/middlewares.py
from scrapy import signals

class MyCustomMiddleware:
    @classmethod
    def from_crawler(cls, crawler):
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def spider_opened(self, spider):
        spider.logger.info('Spider opened: %s' % spider.name)

自定义中间件

自定义中间件可能会在请求和响应中进行处理:

# myproject/middlewares.py
from scrapy import signals

class MyCustomMiddleware:
    def process_request(self, request, spider):
        # 在请求发送之前处理
        spider.logger.info('Request processed: %s' % request)
        return None

    def process_response(self, request, response, spider):
        # 在响应接收后处理
        spider.logger.info('Response processed: %s' % response)
        return response
设置并发请求限制与延时

Scrapy 允许你设置并发请求的数量和延时,以防止被目标网站检测到。这些设置通常在 settings.py 文件中进行:

# myproject/settings.py
CONCURRENT_REQUESTS = 16  # 并发请求限制
DOWNLOAD_DELAY = 1        # 下载延迟,单位:秒

并发请求限制

CONCURRENT_REQUESTS 设置了 Scrapy 同时进行的最大请求数量。

下载延迟

DOWNLOAD_DELAY 设置了下载每个请求之间的最小延迟,以秒为单位。

自定义下载器与处理异常

自定义下载器

自定义下载器可以让你更灵活地处理请求和响应。下载器定义在 settings.py 文件中:

# myproject/settings.py
DOWNLOADER = 'myproject.custom_downloader.CustomDownloader'

下载器类定义在 custom_downloader.py 文件中:

# myproject/custom_downloader.py
from scrapy.core.downloader.handlers.http import HTTPDownloadHandler

class CustomDownloader(HTTPDownloadHandler):
    def download_request(self, request, spider):
        # 自定义下载逻辑
        return super().download_request(request, spider)

处理异常

Scrapy 提供了 errback 方法来处理异常请求:

import scrapy

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

    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(url, callback=self.parse, errback=self.errback_httpbin)

    def errback_httpbin(self, failure):
        # 处理异常
        self.logger.error(repr(failure))
        return failure

errback_httpbin 方法会处理任何请求失败的情况。

Scrapy项目的部署与运行
项目部署的注意事项

部署 Scrapy 项目时,需要注意以下几点:

  1. 性能优化:确保项目的性能优化,例如设置合适的并发请求数量和下载延迟。
  2. 错误处理:确保项目有良好的错误处理机制,以应对各种异常情况。
  3. 日志记录:使用日志记录功能,以便于维护和调试。
  4. 资源使用:确保项目在生产环境中的资源使用合理,避免占用过多系统资源。

设置并发请求限制与延时

settings.py 文件中设置并发请求限制和下载延迟:

# myproject/settings.py
CONCURRENT_REQUESTS = 16  # 并发请求限制
DOWNLOAD_DELAY = 1        # 下载延迟,单位:秒

错误处理

确保项目有良好的错误处理机制,例如通过 try-except 块来捕获和处理异常:

import scrapy

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

    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(url, callback=self.parse, errback=self.errback_httpbin)

    def errback_httpbin(self, failure):
        # 处理异常
        self.logger.error(repr(failure))
        return failure

日志记录

使用日志记录功能,以便于维护和调试:

import scrapy

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

    def parse(self, response):
        self.log('Visited %s' % response.url)

资源使用

确保项目在生产环境中的资源使用合理,避免占用过多系统资源。例如,通过限制并发请求和下载延迟来减少资源消耗。

使用Scrapy Cloud或Docker部署Scrapy项目

Scrapy Cloud

Scrapy Cloud 是一个基于 Scrapy 的云爬虫服务,可以方便地部署和管理 Scrapy 项目:

  1. 安装 Scrapy Cloud CLI

    pip install scrapy-cloud
  2. 配置 Scrapy Cloud

    scrapy_cloud configure
  3. 部署项目
    scrapy_cloud deploy

Docker

使用 Docker 部署 Scrapy 项目可以确保环境的一致性和可移植性:

  1. 创建 Dockerfile

    FROM python:3.8-slim
    
    WORKDIR /app
    
    COPY requirements.txt requirements.txt
    RUN pip install -r requirements.txt
    
    COPY . .
    
    CMD ["scrapy", "crawl", "myspider"]
  2. 构建 Docker 镜像

    docker build -t myproject .
  3. 运行 Docker 容器
    docker run -it myproject
监控Scrapy项目的运行状态

Scrapy 本身没有内置的监控工具,但可以使用日志和第三方监控工具来监控项目运行状态:

  1. 日志监控
    Scrapy 会生成详细的日志信息,可以通过日志文件来监控项目的运行情况。

  2. 第三方监控工具
    使用如 Prometheus、Grafana 等工具来监控 Scrapy 项目的运行状态和性能。
Scrapy常见问题与资源分享
Scrapy常见问题与解决方法
  1. 网站被封禁:增加下载延迟和减少并发请求,确保遵守目标网站的使用政策。
  2. 爬虫速度慢:优化爬虫逻辑,减少不必要的请求,提高解析效率。
  3. 数据提取不准确:检查选择器和解析逻辑,确保选择器正确匹配目标数据。
  4. 内存泄漏:确保及时清理不再使用的对象,避免内存泄漏。
Scrapy学习资源推荐
  • Scrapy 官方文档:详细介绍了 Scrapy 的安装、配置和使用方法。
  • Scrapy 中文社区:提供 Scrapy 的教程、案例和问答。
  • 慕课网:提供了 Scrapy 的在线课程,适合不同水平的学习者。
  • GitHub:Scrapy 项目源代码和相关示例在 GitHub 上公开,可以参考学习。
Scrapy中文社区与论坛介绍
  • Scrapy 中文社区:Scrapy 中文社区是 Scrapy 在中国的官方交流平台,提供了丰富的资源和讨论环境。
  • GitHub:GitHub 上有大量的 Scrapy 开源项目和示例代码,可以参考学习。
  • Stack Overflow:Stack Overflow 是一个问答社区,你可以在这里找到 Scrapy 相关的问题和解答。
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消