Scrapy框架入门 - Python强大的爬虫框架

Scrapy是Python最专业的爬虫框架,专为大规模爬取任务设计。它提供了完整的爬虫开发工具链,包括请求调度、数据解析、数据存储等。

一、为什么选择Scrapy

相比requests+BeautifulSoup的组合,Scrapy具有以下优势:

  • 异步请求,性能更高
  • 内置请求调度和去重
  • 完善的调试和扩展机制
  • 支持数据管道存储
  • 强大的选择器支持

二、安装Scrapy

pip install scrapy

# 验证安装
scrapy version

三、创建Scrapy项目

# 创建新项目
scrapy startproject myspider
cd myspider

# 创建爬虫
scrapy genspider example example.com

四、Scrapy项目结构

myspider/
├── scrapy.cfg           # 项目配置
└── myspider/
    ├── __init__.py
    ├── items.py         # 定义数据结构
    ├── middlewares.py   # 中间件
    ├── pipelines.py     # 数据管道
    └── spiders/         # 爬虫目录
        └── example.py   # 爬虫文件

五、编写第一个爬虫

import scrapy

class ExampleSpider(scrapy.Spider):
    name = 'example'
    allowed_domains = ['example.com']
    start_urls = ['https://example.com']
    
    def parse(self, response):
        # 提取页面标题
        title = response.css('title::text').get()
        yield {'title': title}
        
        # 提取所有链接
        for link in response.css('a::attr(href)').getall():
            if link.startswith('http'):
                # 跟进链接
                yield response.follow(link, callback=self.parse)

六、运行爬虫

# 运行爬虫
scrapy crawl example

# 保存到文件
scrapy crawl example -o output.json
scrapy crawl example -o output.csv

# 指定爬取深度
scrapy crawl example -s DEPTH_LIMIT=3

七、选择器详解

Scrapy支持CSS选择器和XPath选择器:

7.1 CSS选择器

# 基本选择器
response.css('title::text').get()           # 标签文本
response.css('div.content p::text').getall()  # 多级选择
response.css('.container::text').get()      # class选择器
response.css('#header::text').get()          # id选择器

# 伪元素选择器
response.css('li:first-child::text').get()
response.css('li:nth-child(2)::text').get()
response.css('a::attr(href)').get()       # 获取属性

7.2 XPath选择器

# 基本选择器
response.xpath('//title/text()').get()
response.xpath('//div[@class="content"]//p/text()').getall()
response.xpath('//a[@href]/@href').getall()

# 轴(Axes)
response.xpath('//div/child::p')            # 子元素
response.xpath('//div/parent::body')        # 父元素
response.xpath('//p/following-sibling::a') # 后续兄弟

八、数据解析实战

import scrapy

class NewsSpider(scrapy.Spider):
    name = 'news'
    start_urls = ['https://news.example.com']
    
    def parse(self, response):
        # 提取新闻列表
        for article in response.css('.news-item'):
            yield {
                'title': article.css('h2.title::text').get(),
                'link': article.css('a::attr(href)').get(),
                'summary': article.css('.summary::text').get(),
                'date': article.css('.date::text').get(),
            }
        
        # 翻页
        next_page = response.css('.next a::attr(href)').get()
        if next_page:
            yield response.follow(next_page, callback=self.parse)

九、Item和Pipeline

9.1 定义Item

# items.py
import scrapy

class NewsItem(scrapy.Item):
    title = scrapy.Field()
    link = scrapy.Field()
    summary = scrapy.Field()
    date = scrapy.Field()
    author = scrapy.Field()

9.2 使用Item

import scrapy
from myspider.items import NewsItem

class NewsSpider(scrapy.Spider):
    name = 'news'
    
    def parse(self, response):
        item = NewsItem()
        item['title'] = response.css('h1::text').get()
        item['link'] = response.url
        yield item

9.3 Pipeline数据处理

# pipelines.py
class SaveToJsonPipeline:
    def open_spider(self, spider):
        self.file = open('items.json', 'w')
    
    def close_spider(self, spider):
        self.file.close()
    
    def process_item(self, item, spider):
        line = json.dumps(dict(item)) + '\n'
        self.file.write(line)
        return item

十、请求和响应

10.1 发送请求

from scrapy import Request

def parse(self, response):
    # GET请求
    yield Request(url, callback=self.parse_detail)
    
    # POST请求
    yield FormRequest(
        url,
        formdata={'key': 'value'},
        callback=self.parse_result
    )

10.2 请求参数

yield Request(
    url,
    callback=self.parse,
    errback=self.error_handler,
    meta={'item': item},  # 传递数据
    headers={'User-Agent': 'Mozilla/5.0'},
    cookies={'session': 'abc'},
    dont_filter=True,  # 禁用去重
    priority=10,      # 请求优先级
)

十一、中间件

11.1 下载中间件

# middlewares.py
class ProxyMiddleware:
    def process_request(self, request, spider):
        request.meta['proxy'] = 'http://127.0.0.1:7890'

class UserAgentMiddleware:
    def process_request(self, request, spider):
        request.headers['User-Agent'] = (
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
            'AppleWebKit/537.36'
        )

11.2 启用中间件

# settings.py
DOWNLOADER_MIDDLEWARES = {
    'myspider.middlewares.ProxyMiddleware': 543,
    'myspider.middlewares.UserAgentMiddleware': 542,
}

十二、总结

Scrapy是专业爬虫的首选框架,功能强大、性能优异。适合大规模数据采集任务。

发表回复

后才能评论