当前位置:首页>python>Python爬虫——Scrapy框架怎么用?

Python爬虫——Scrapy框架怎么用?

  • 2026-10-11 08:35:39
Python爬虫——Scrapy框架怎么用?
关注+星标,每天学习Python新技能

来源:网络

Scrapy 是一个为了爬取网站数据、提取结构性数据而编写的开源 Python 应用框架。它基于 Twisted 异步网络框架开发,能够同时处理多个请求,被广泛用于数据挖掘、监测和自动化测试等领域。

1

安装与项目结构

  1. 安装

pip install scrapy

  1. 创建项目

终端输入:scrapy startproject scrapy_project

题外话:看见这个指令我瞬间就觉得眼熟,好像python里面还有一个项目创建命令几乎如出一辙。django-admin startproject myproject,发现没有就是它,python web的框架。它俩有什么共同点呢?

结论是,Django 和 Scrapy 对项目目录结构都有强制要求,比如 Scrapy 必须有 spiders 文件夹,Django 必须有 settings.py。 它们必须提供 startproject 命令,否则用户根本无法手动搭建出正确的运行环境。startproject 是“重量级/全功能”框架的标配特征,代表了一种“约定优于配置”的设计理念。

3. 项目目录结构

文件

说明

spiders

存放爬虫代码的目录

items.py

定义要抓取的数据结构

middlewares.py

中间件(代理、UA池等)

pipelines.py  

数据管道,处理抓取的数据(清洗、存储等)

settings.py  

全局配置文件

scrapy.cfg

部署配置文件

2

实战演练

爬取网站:http://quotes.toscrape.com/

  1. 定义数据结构

在 items.py 中定义要抓取的字段

import scrapyclass QuoteItem(scrapy.Item):    # define the fields for your item here like:    # name = scrapy.Field()    text = scrapy.Field()  # 内容    author = scrapy.Field()  # 作者    tags = scrapy.Field()  # 标签

2. 编写爬虫文件

在 spiders 目录下创建 quotes_spider.py

可以自己创建,也可以指令创建:

cd scrapy_project #先进入项目目录# scrapy genspider 文件名 url(网站域名)scrapy genspider quotes_spider http://quotes.toscrape.com/

建议用指令创建,因为它会给你搭出大致框架,我们只需要完善逻辑。

import scrapyfrom scrapy_project.items import QuoteItemclass QuotesSpiderSpider(scrapy.Spider):    name = "quotes_spider"  # 爬虫文件名    allowed_domains = ["quotes.toscrape.com"]  # 网站域名    start_urls = ["http://quotes.toscrape.com"]  # 第一个要抓取的url    offset = 1    def parse(self, response):        # 解析页面        for i in response.xpath('//div[@class="col-md-8"]/div'):            quote = QuoteItem()            quote['text'] = i.xpath('.//span[@class="text"]/text()').get()            quote['author'] = i.xpath('.//small[@class="author"]/text()').get()            # tags 通常有多个,所以用 .getall() 提取所有匹配到的文本,返回一个字符串列表            quote['tags'] = i.xpath('.//a[@class="tag"]/text()').getall()            yield quote  # 将数据提交给 Pipeline        # 提取下一页链接,实现自动翻页        # 方案一:        if self.offset <= 10:            self.offset += 1            url = f"http://quotes.toscrape.com/page/{self.offset}/"            yield scrapy.Request(url=url, callback=self.parse)        # 方案二:        # next_page = response.xpath('//li[@class="next"]/a/@href').get()        # if next_page is not None:        #     yield response.follow(next_page,callback=self.parse)

有两个易错点,即新手最容易踩坑的概念:“XPath 的上下文”和“选择器的返回值类型”。

(1)循环里面的 i.xpath(...) 写法里不要少了至关重要的点:.(点号)。

  • i.xpath('//span...'):开头的 // 代表从整个文档的根节点开始找。这意味着,不管循环到第几次,它都会去整个网页里把所有的名言 span 都抓回来塞给这一个 item。

  • i.xpath('.//span...'):开头的 . 代表从当前节点 i 内部开始找。这才是我们要的“在当前这条名言里找作者、找正文”。

(2)如果你的item返回的是“列表”和“Selector对象”,那就要注意看,你是不是忘了加get()。

  • Scrapy 的 .xpath() 方法总是返回一个列表(类似数组的 SelectorList 对象)。哪怕页面上只有一个匹配结果,它也放在列表里返回给你。

  • 解决办法: 你需要用 .get() 或 .getall() 方法把数据从 Selector 对象里“提取”出来变成字符串。

(3)总结

在 Scrapy 解析数据时,记住这三步:

  • 定范围:for i in ... 循环拿到了每一个条目的节点(这就是范围)。

  • 找子元素:在循环内部写 XPath 时,一定要以 . 开头(如 .//div),否则就会跳出范围,搜全页。

  • 提数据:

    如果只要一个数据(如标题、作者):用 .xpath(...).get()。

    如果要一组数据(如标签,如下图所示):用 .xpath(...).getall(),

3. 编写管道

在 pipelines.py 中处理数据(数据清洗、存入数据库等),需要利用 Scrapy 提供的三个特殊方法:open_spider、close_spider 和 process_item。

from itemadapter import ItemAdapterimport pymysqlfrom scrapy_project.settings import *class ScrapyProjectPipeline:    # 在这里进行数据清洗    def process_item(self, item, spider):        item['text'] = item['text'].strip("“”")        return item  # 必须返回 item,给后续的 pipeline 使用class MysqlPipeline:    # 1. 爬虫开始时:连接数据库    def open_spider(self, spider):        self.conn = pymysql.connect(            host=MYSQL_HOST,            port=MYSQL_PORT,            user=MYSQL_USER,            password=MYSQL_PASSWORD,            database=MYSQL_DATABASE,        )        self.cursor = self.conn.cursor()        spider.logger.info("数据库连接成功!")    # 2. 爬虫结束时:关闭连接    def close_spider(self, spider):        self.cursor.close()        self.conn.close()        spider.logger.info("数据库连接关闭!")    # 3. 处理每一条 Item:执行 SQL 插入    def process_item(self, item, spider):        try:            # 别忘了提前在数据库里建表:            # CREATE TABLE quotes_table (            #     id INT AUTO_INCREMENT PRIMARY KEY,            #     text VARCHAR(500),            #     author VARCHAR(50),            #     tags VARCHAR(255)            # );            sql = "INSERT INTO quotes_table (text,author,tags) VALUES (%s,%s,%s)"            # 处理数据:tags 如果是列表,用 join 转成字符串            tags_str = ",".join(item['tags']) ifisinstance(item['tags'], list) else item['tags']            self.cursor.execute(sql, (item['text'], item['author'], tags_str))            self.conn.commit()            spider.logger.info("成功插入数据!")        except Exception as e:            self.conn.rollback()            spider.logger.error(f"数据库插入失败: {e}")        return item  # 必须返回 item,给后续的 pipeline 使
  1. 配置设置

在 settings.py 中开启 Pipeline 并设置 User-Agent:

# 1.设置 User-Agent,伪装成浏览器USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"# 2.开启 Pipeline,数字越小优先级越高ITEM_PIPELINES = {   "scrapy_project.pipelines.ScrapyProjectPipeline": 300, # 负责清洗   "scrapy_project.pipelines.MysqlPipeline":400# 负责存储 (数字越大,优先级越低,越后执行)}# 3.配置数据库连接参数MYSQL_HOST = "127.0.0.1"MYSQL_PORT = 3306MYSQL_USER = "root"MYSQL_PASSWORD = "123456"MYSQL_DATABASE = "my_db"

5. 运行爬虫

在项目根目录(scrapy.cfg 所在目录)下运行:

scrapy crawl quotes_spider

就可以得到以下结果:

3

选择器

Scrapy 支持两种选择器:

  • XPath Selector: response.xpath('//div[@class="col-md-8"]/div'),支持根据文本内容查找节点,适合复杂的结构提取。

  • CSS Selector: response.css('div.col-md-8 div'),适合前端熟悉的开发者。比如上面示例换成css选择器如下:

for i in response.css('div.col-md-8 > div'):  # 或者简写为 'div.col-md-8 div'    quote = QuoteItem()# 1. 提取 text# XPath: .//span[@class="text"]/text()# CSS: span.text 提取标签,::text 提取文本,.get() 取第一个    quote['text'] = i.css('span.text::text').get()# 2. 提取 author# XPath: .//small[@class="author"]/text()# CSS: small.author 提取标签,::text 提取文本    quote['author'] = i.css('small.author::text').get()# 3. 提取 tags# XPath: .//a[@class="tag"]/text()# CSS: a.tag 提取标签,::text 提取文本,.getall() 取全部    quote['tags'] = i.css('a.tag::text').getall()    yield quote
  • 核心语法对比:

功能

XPath 写法

CSS 写法

说明

按 Class 查找

div[@class="quote"]

div.quote

CSS 用 . 代表 class

按 ID 查找

div[@id="main"]

div#main

CSS 用 # 代表 id

提取文本

/text()

::text

CSS 用伪元素 ::text

提取属性

/@href

::attr(href)

CSS 用 ::attr(属性名)

提取第一个

xpath(…).get()

css(…).get()

结果相同

提取全部

xpath(…).getall()

css(…).getall()

结果相同

长按或扫描下方二维码,免费获取 Python公开课和大佬打包整理的几百G的学习资料,内容包含但不限于Python电子书、教程、项目接单、源码等等

▲扫描二维码-免费领取

推荐阅读

使用python实现录音功能(实用)

不要再用Print来debug了

10个内置在 Pandas 中却常被忽略的向量化操作

机器学习特征工程:缩放、编码、聚合、嵌入与自动化

点击 阅读原文了解更多

最新文章

随机文章