跳转到内容

Python Scrapy 框架

来自代码酷
Admin留言 | 贡献2025年4月28日 (一) 21:10的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

Python Scrapy框架[编辑 | 编辑源代码]

Scrapy 是一个用 Python 编写的开源网络爬虫框架,用于高效地从网站提取结构化数据。它提供了完整的工具链,包括请求调度、数据解析、存储和导出等功能,适用于数据挖掘、监测和自动化测试等场景。

核心概念[编辑 | 编辑源代码]

Scrapy 基于异步 I/O(Twisted)实现高性能爬取,其核心组件包括:

  • 引擎(Engine):控制数据流,协调各组件工作
  • 调度器(Scheduler):管理请求队列
  • 下载器(Downloader):获取网页内容
  • 爬虫(Spider):定义爬取逻辑和数据提取规则
  • 项目管道(Item Pipeline):处理提取的数据
  • 下载器中间件(Downloader Middleware):处理请求/响应
  • 爬虫中间件(Spider Middleware):处理爬虫输入/输出

graph LR A[Spider] -->|生成Request| B[Engine] B -->|发送Request| C[Scheduler] C -->|调度Request| B B -->|发送Request| D[Downloader] D -->|返回Response| B B -->|返回Response| A A -->|生成Item| E[Item Pipeline]

安装与基本使用[编辑 | 编辑源代码]

安装 Scrapy:

pip install scrapy

创建项目:

scrapy startproject myproject

生成基础爬虫:

cd myproject
scrapy genspider example example.com

编写爬虫[编辑 | 编辑源代码]

以下是一个简单的爬虫示例,从 quotes.toscrape.com 提取名言:

import scrapy

class QuoteSpider(scrapy.Spider):
    name = "quotes"
    start_urls = ['http://quotes.toscrape.com/page/1/']

    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('small.author::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, callback=self.parse)

输出示例:

{
    "text": "The world as we have created it is a process of our thinking...",
    "author": "Albert Einstein",
    "tags": ["change", "deep-thoughts", "thinking", "world"]
}

数据处理管道[编辑 | 编辑源代码]

项目管道用于清洗、验证和存储数据。示例管道:

class MyprojectPipeline:
    def process_item(self, item, spider):
        # 数据清洗示例:去除名言中的引号
        item['text'] = item['text'].strip('“”')
        return item

在 settings.py 中启用管道:

ITEM_PIPELINES = {
    'myproject.pipelines.MyprojectPipeline': 300,
}

高级功能[编辑 | 编辑源代码]

中间件开发[编辑 | 编辑源代码]

下载器中间件示例(随机User-Agent):

from scrapy import signals
import random

class RandomUserAgentMiddleware:
    user_agents = [
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',
        'Mozilla/5.0 (X11; Linux x86_64)'
    ]

    def process_request(self, request, spider):
        request.headers['User-Agent'] = random.choice(self.user_agents)

分布式爬取[编辑 | 编辑源代码]

使用 scrapy-redis 实现分布式:

# settings.py
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
REDIS_URL = 'redis://localhost:6379'

性能优化[编辑 | 编辑源代码]

Scrapy 性能指标公式: 吞吐量=成功抓取的页面数总时间

优化技巧:

  • 调整 CONCURRENT_REQUESTS(默认16)
  • 使用 AUTOTHROTTLE 扩展自动调整速度
  • 启用缓存(HTTPCACHE_ENABLED = True)

实际应用案例[编辑 | 编辑源代码]

电商价格监控系统: 1. 爬取目标电商网站产品页面 2. 提取价格、库存、评价数据 3. 存储到数据库 4. 触发价格变化警报

技术要点

  • 使用 Splash 处理 JavaScript 渲染
  • 设置合理的下载延迟(DOWNLOAD_DELAY)
  • 实现自动重试机制(RETRY_TIMES)

最佳实践[编辑 | 编辑源代码]

  • 遵守 robots.txt 规则
  • 设置合理的下载延迟
  • 处理异常响应(404, 503等)
  • 使用 logging 记录爬取过程
  • 定期清理重复请求

常见问题[编辑 | 编辑源代码]

Q: 如何处理动态加载的内容? A: 使用 Splash 或 selenium 中间件

Q: 如何避免被网站屏蔽? A: 使用代理中间件,设置随机 User-Agent 和请求延迟

Q: 如何增量爬取? A: 实现去重逻辑,或使用 scrapy-deltafetch 扩展

学习资源[编辑 | 编辑源代码]

通过本指南,您应该已经掌握了 Scrapy 的基本使用和核心概念。建议从简单项目开始实践,逐步探索框架的高级功能。