当前位置: 首页 > news >正文

爬虫框架Scrapy从入门到实战

一、Scrapy框架概述

1.1 什么是Scrapy

Scrapy是一个基于Twisted的异步网络爬虫框架,具有以下特性:

  • 内置数据提取器(Selector)

  • 完善的中间件扩展体系

  • 自动的请求调度机制

  • 支持多种数据存储方式

1.2 Scrapy vs Requests

特性ScrapyRequests+BS4
并发能力异步高性能同步单线程
项目结构标准化目录自由脚本结构
扩展性中间件系统需手动实现
适用场景大型爬虫项目小规模数据采集

二、环境搭建

2.1 安装Scrapy

pip install scrapy
# 验证安装
scrapy version  # 应输出版本号如2.11.0

2.2 创建项目

scrapy startproject book_scraper
cd book_scraper
scrapy genspider book_spider books.toscrape.com

生成的项目结构:

book_scraper/
├── scrapy.cfg
└── book_scraper/
    ├── __init__.py
    ├── items.py       # 数据容器定义
    ├── middlewares.py # 中间件配置
    ├── pipelines.py   # 数据管道
    ├── settings.py    # 全局配置
    └── spiders/       # 爬虫目录
        └── book_spider.py

三、核心组件详解

3.1 Spider类(爬虫核心)

python

复制

import scrapy

class BookSpider(scrapy.Spider):
    name = "book_spider"  # 爬虫唯一标识
    allowed_domains = ["books.toscrape.com"]
    start_urls = ["http://books.toscrape.com/"]

    def parse(self, response):
        # 解析逻辑
        passimport scrapy

class BookSpider(scrapy.Spider):
    name = "book_spider"  # 爬虫唯一标识
    allowed_domains = ["books.toscrape.com"]
    start_urls = ["http://books.toscrape.com/"]

    def parse(self, response):
        # 解析逻辑
        pass

3.2 Item类(数据结构)

# items.py
import scrapy

class BookItem(scrapy.Item):
    title = scrapy.Field()
    price = scrapy.Field()
    rating = scrapy.Field()
    stock = scrapy.Field()

3.3 Pipeline(数据处理管道)

# pipelines.py
class BookPipeline:
    def process_item(self, item, spider):
        # 数据清洗/存储逻辑
        if item['price']:
            item['price'] = float(item['price'].replace('£', ''))
        return item

3.4 Middleware(中间件系统)

# middlewares.py
class RandomDelayMiddleware:
    def process_request(self, request, spider):
        # 设置随机请求延迟(0.5-1.5秒)
        delay = random.uniform(0.5, 1.5)
        request.meta['download_timeout'] = delay

四、完整爬虫实战

4.1 编写爬虫逻辑

# spiders/book_spider.py
class BookSpider(scrapy.Spider):
    name = 'book_spider'
    
    def start_requests(self):
        urls = [f"http://books.toscrape.com/catalogue/page-{i}.html" 
                for i in range(1,51)]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        books = response.css('article.product_pod')
        for book in books:
            item = BookItem()
            item['title'] = book.css('h3 a::attr(title)').get()
            item['price'] = book.css('p.price_color::text').get()
            item['rating'] = book.css('p.star-rating::attr(class)').get().split()[-1]
            yield item

        # 自动翻页(已由start_requests实现)

4.2 配置settings.py

# 启用Pipeline
ITEM_PIPELINES = {
   'book_scraper.pipelines.BookPipeline': 300,
}

# 遵守robots协议
ROBOTSTXT_OBEY = True  

# 并发控制
CONCURRENT_REQUESTS = 16  
DOWNLOAD_DELAY = 0.5

4.3 运行爬虫

scrapy crawl book_spider -o books.csv
# 支持导出格式:json, csv, xml等

五、高级功能扩展

5.1 动态网页处理(Selenium中间件)

# middlewares.py
from selenium import webdriver

class SeleniumMiddleware:
    def process_request(self, request, spider):
        if request.meta.get('selenium'):
            driver = webdriver.Chrome()
            driver.get(request.url)
            html = driver.page_source
            driver.quit()
            return HtmlResponse(url=request.url, body=html, encoding='utf-8')

5.2 分布式爬虫(Redis集成)

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

5.3 自动限速算法

# settings.py
AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_START_DELAY = 5.0
AUTOTHROTTLE_MAX_DELAY = 60.0

六、调试技巧

6.1 Scrapy Shell

scrapy shell "http://books.toscrape.com"
>>> response.css('title::text').get()
'All products | Books to Scrape - Sandbox'

6.2 日志分级

scrapy crawl book_spider -L INFO  # DEBUG/INFO/WARNING/ERROR

6.3 中间件断点调试

# 在middleware中插入调试代码
import pdb; pdb.set_trace()

七、最佳实践

  1. 遵守robots.txt:设置ROBOTSTXT_OBEY = True

  2. 设置User-Agent:使用随机User-Agent中间件

  3. 异常处理:覆盖spider_error回调

  4. 数据去重:使用scrapy-deltafetch扩展

  5. 监控报警:集成ScrapydWeb可视化面板

八、常见问题解答

Q1:如何处理登录验证?

# 在Spider中实现登录
def start_requests(self):
    return [scrapy.FormRequest(
        'https://example.com/login',
        formdata={'user': 'admin', 'pass': 'secret'},
        callback=self.after_login
    )]

Q2:如何避免被封IP?

  • 使用代理中间件

  • 设置合理的DOWNLOAD_DELAY

  • 使用scrapy-rotating-proxies扩展

Q3:如何抓取JavaScript渲染的页面?

  • 使用Selenium中间件

  • 集成Splash服务

  • 使用scrapy-playwright


本文技术要点

  1. Scrapy框架的组件化设计

  2. 可扩展的中间件系统

  3. 生产级爬虫的最佳实践

  4. 分布式爬虫架构基础

  5. 常见反爬应对策略

下一步学习建议

  • 研究Scrapy源码理解运行机制

  • 学习Scrapy-Redis实现分布式

  • 实践反反爬技术(验证码识别、指纹伪装)

相关文章:

  • android初学
  • cython编译pyd并且c调用
  • 腾讯四面面经
  • Qt-Q_ENUM宏和QMetaEnum类
  • rocky linux 与centos系统的区别
  • 16.Linux蓝牙从硬件驱动到应用
  • HTTP核心知识
  • vue插槽传送和接收item
  • pyqt5报错:qt.qpa.plugin: Could not find the Qt platform plugin “xcb“(已解决)
  • Linux安装Ollama+MaxKB建立本地知识库
  • 2024年MathorCup数学建模C题物流网络分拣中心货量预测及人员排班解题全过程文档加程序
  • SpringBoot(8)——Springboot数据层开发
  • 【Linux文件IO】Linux中文件属性与目录操作的API介绍和用法
  • 第三章 | 初识 Solidity:开发环境搭建 第一个智能合约{介绍篇}
  • Codeforces Round 1012 (Div. 2) 3.23
  • 零基础上手Python数据分析 (8):Pandas 核心数据结构 Series 和 DataFrame
  • 【博客节选】再谈Unity 的 root motion
  • 【算法】入门详解
  • asp.net mvc 向前端响应json数据。用到jquery
  • 描述@keyframes规则在 CSS 动画中的原理及作用,如何创建一个简单的动画
  • 湖北宜昌:在青山绿水间解锁乡村振兴“密码”
  • 警惕“全网最低价”等宣传,市监总局和中消协发布直播消费提示
  • 美英达成贸易协议,美股集体收涨
  • 本科生已发14篇SCI论文被指由其教授父亲挂名,重庆大学成立工作组核实
  • 越秀地产前4个月销售额约411.2亿元,达年度销售目标的34.1%
  • 胖东来发布和田玉、翡翠退货说明:不扣手续费等任何费用