0x01 框架概述

Scrapy 是基于 Python 的一个非常流行的网络爬虫框架,可以用来抓取 Web 站点并从页面中提取结构化的数据

(1)核心组件

  • 引擎:用来控制整个系统的数据处理流程
  • 调度器:从引擎接收请求并排序列入队列,并在引擎发出请求后返还
  • 下载器:抓取网页并将网页内容返还给蜘蛛
  • 蜘蛛程序:蜘蛛是用户自定义的用来解析网页并抓取特定 URL 的类
  • 数据管道:处理蜘蛛从网页中抽取的数据条目
  • 中间件:介于引擎和其他组件的钩子框架,提供自定义的代码来拓展 Scrapy 的功能

(2)工作流程

  1. 引擎问询蜘蛛需要处理的网站,并让蜘蛛交出第一个需要处理的 URL
  2. 引擎让调度器将需要处理的 URL 放入队列
  3. 引擎从调度中获取需要开始爬取的页面
  4. 调度将下一个需要爬取的 URL 返回到引擎,引擎将该 URL 通过下载中间件发送到下载器
  5. 当网页被下载器下载完成后,响应内容通过下载中间件发送到引擎;下载失败则引擎会通知调度记录并稍后重新下载该 URL
  6. 引擎收到下载器的响应并通过蜘蛛中间件发送到蜘蛛进行处理
  7. 蜘蛛处理响应并返回爬取到的数据条目,此外还要将需要跟进的新的 URL 发送给引擎
  8. 引擎将抓取到的数据条目送入数据管道,把新的 URL 发送给调度器放入队列中

0x02 第一个程序

(1)创建项目

a. 命令行

  1. 使用命令 pip install scrapy 安装 Scrapy

    cssselect == 1.1.0

    parsel == 1.6.0

  2. 使用命令 scrapy startproject demo 创建项目 Demo

  3. 在项目目录下,使用命令 scrapy genspider douban movie.douban.com 创建蜘蛛程序

  4. 项目目录如下:

    demo
    │ scrapy.cfg

    └─demo
    │ items.py
    │ middlewares.py
    │ pipelines.py
    │ settings.py
    │ __init__.py

    └─spiders
    │ douban.py
    └─ __init__.py

b. PyCharm

  • 在设置中添加 Scrapy 包

(2)编写和运行程序

  • 提供种子 URL并解析页面:douban.py

    import scrapy
    
    from ..items import MovieItem
    
    class DoubanSpider(scrapy.Spider):
    name = "douban"
    allowed_domains = ["movie.douban.com"]
    start_urls = ["https://movie.douban.com/top250"] def parse(self, response: scrapy.http.HtmlResponse, **kwargs):
    select = scrapy.Selector(response)
    list_items = select.css('#content > div > div.article > ol > li')
    for item in list_items:
    movie_item = MovieItem()
    movie_item['title'] = item.css('span.title::text').extract_first()
    movie_item['rate'] = item.css('span.rating_num::text').extract_first()
    movie_item['inq'] = item.css('span.inq::text').extract_first()
    yield movie_item
  • 数据组成 Item 对象:items.py

    class MovieItem(scrapy.Item):
    title = scrapy.Field()
    rate = scrapy.Field()
    inq = scrapy.Field()
  • 修改请求头信息:settings.py

    # 遵循爬虫协议
    ROBOTSTXT_OBEY = True
    # 用户代理
    USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.1.4031 SLBChan/103"
    # 并发请求数
    CONCURRENT_REQUESTS = 32
    # 下载延迟
    DOWNLOAD_DELAY = 3
    # 随机化下载延迟
    RANDOMIZE_DELAY = True
    # 配置数据管道
    ITEM_PIPELINES = {
    "demo.pipelines.DemoPipeline": 300,
    }
  • 使用命令 scrapy crawl douban -o douban.csv 运行爬虫程序并将结果输出到 douban.csv 中

    • -o 改为 -O 表示覆写 douban.csv

(3)多页面爬取

  • 在 douban.py 中修改,将 start_urls = ["https://movie.douban.com/top250"] 替换为以下内容:

    def start_requests(self):
    for page in range(10):
    yield Request(url=f"https://movie.douban.com/top250?start={page*25}&filter=")

0x03 数据管道

  • 使用命令 pip freeze > requirements.txt 生成依赖清单
  • 使用命令 pip install -r requirements.txt 自动添加缺少的依赖

(1)Excel

  • 添加依赖 openpyxl

  • 在 pipelines.py 中添加管道

    import openpyxl
    
    class DemoPipeline:
    def __init__(self):
    self.workbook = None
    self.worksheet = None # 开启蜘蛛程序时执行以下函数
    def open_spider(self, spider):
    # 创建工作簿
    self.workbook = openpyxl.Workbook()
    # 获取默认工作表
    self.worksheet = self.workbook.active
    # 修改工作表标题
    self.worksheet.title = "Top250"
    # 设置表头
    self.worksheet.append(('标题', '评分', '评价')) # 关闭蜘蛛程序时执行以下函数
    def close_spider(self, spider):
    # 保存数据
    self.workbook.save('top250.xlsx') # 数据处理
    def process_item(self, item, spider):
    title = item.get('title', '')
    rate = item.get('rate', 0)
    inq = item.get('inq', '')
    self.worksheet.append((title, rate, inq))
    return item
  • 在 settings.py 中配置管道

    ITEM_PIPELINES = {
    "demo.pipelines.DemoPipeline": 300,
    }
    • 值越小,优先级越高

(2)MySQL

创建数据库

create schema if not exists scrapy;
use scrapy;
drop table if exists top;
create table top (
id int auto_increment comment '编号',
title varchar(50) not null comment '标题',
rate decimal(3, 1) not null comment '评分',
inq varchar(255) default '' comment '评论',
primary key (id)
) engine=innodb comment='top250';

a. 单次写入

  • 添加依赖 pymysql

  • 在 pipelines.py 中添加管道

    import pymysql
    
    class DemoPipeline:
    def __init__(self):
    self.connection = None
    self.cursor = None # 开启蜘蛛程序时执行以下函数
    def open_spider(self, spider):
    # 连接数据库
    self.connection = pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    password='root',
    database='scrapy'
    )
    # 设置游标
    self.cursor = self.connection.cursor() # 关闭蜘蛛程序时执行以下函数
    def close_spider(self, spider):
    # 提交修改
    self.connection.commit()
    # 关闭连接
    self.connection.close() # 数据处理
    def process_item(self, item, spider):
    title = item.get('title', '')
    rate = item.get('rate', 0)
    inq = item.get('inq', '')
    # SQL 插入操作
    self.cursor.execute('INSERT INTO top (title, rate, inq) values (%s, %s, %s)', (title, rate, inq))
    return item

b. 批量写入

  • 修改 pipelines.py

    class DemoPipeline:
    def __init__(self):
    self.connection = None
    self.cursor = None
    self.data = [] # ... # 数据处理
    def process_item(self, item, spider):
    title = item.get('title', '')
    rate = item.get('rate', 0)
    inq = item.get('inq', '')
    self.data.append((title, rate, inq))
    # SQL 插入操作
    if len(self.data) >= 50:
    self.cursor.executemany('INSERT INTO top (title, rate, inq) values (%s, %s, %s)', self.data)
    self.connection.commit()
    self.data.clear()
    return item

0x04 中间件

(1)下载中间件

DownloaderMiddleware

  • 下载中间件是一种拦截器,可以拦截请求和响应

  • 在 middlewares.py 中设置下载中间件

    def process_request(self, request, spider):
    cookies = ''
    cookies_dict = {}
    for item in cookies.split('; '):
    key, value = item.split('=', maxsplit=1)
    cookies_dict[key] = value
    request.cookies = cookies_dict
    return None
  • 在 settings.py 中配置下载中间件

    DOWNLOADER_MIDDLEWARES = {
    "demo.middlewares.DemoDownloaderMiddleware": 543,
    }

(2)蜘蛛中间件

SpiderMiddleware

-End-

Scrapy 基础入门的更多相关文章

  1. 0.Python 爬虫之Scrapy入门实践指南(Scrapy基础知识)

    目录 0.0.Scrapy基础 0.1.Scrapy 框架图 0.2.Scrapy主要包括了以下组件: 0.3.Scrapy简单示例如下: 0.4.Scrapy运行流程如下: 0.5.还有什么? 0. ...

  2. [转]Scrapy简单入门及实例讲解

    Scrapy简单入门及实例讲解 中文文档:   http://scrapy-chs.readthedocs.io/zh_CN/0.24/ Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用 ...

  3. Scrapy爬虫入门系列3 将抓取到的数据存入数据库与验证数据有效性

    抓取到的item 会被发送到Item Pipeline进行处理 Item Pipeline常用于 cleansing HTML data validating scraped data (checki ...

  4. Python3零基础入门学习视频+源码+课件+习题-小甲鱼

    目录 1. 介绍 2. 目录 3. 下载地址 1. 介绍 适用人群 完全零基础入门,不需要任何前置知识. 课程概述 本系列教程面向零基础的同学,是一个深入浅出,通俗易懂的Python3视频教程. 前半 ...

  5. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  6. 「译」JUnit 5 系列:基础入门

    原文地址:http://blog.codefx.org/libraries/junit-5-basics/ 原文日期:25, Feb, 2016 译文首发:Linesh 的博客:JUnit 5 系列: ...

  7. .NET正则表达式基础入门

    这是我第一次写的博客,个人觉得十分不容易.以前看别人写的博客文字十分流畅,到自己来写却发现十分困难,还是感谢那些为技术而奉献自己力量的人吧. 本教程编写之前,博主阅读了<正则指引>这本入门 ...

  8. 从零3D基础入门XNA 4.0(2)——模型和BasicEffect

    [题外话] 上一篇文章介绍了3D开发基础与XNA开发程序的整体结构,以及使用Model类的Draw方法将模型绘制到屏幕上.本文接着上一篇文章继续,介绍XNA中模型的结构.BasicEffect的使用以 ...

  9. 从零3D基础入门XNA 4.0(1)——3D开发基础

    [题外话] 最近要做一个3D动画演示的程序,由于比较熟悉C#语言,再加上XNA对模型的支持比较好,故选择了XNA平台.不过从网上找到很多XNA的入门文章,发现大都需要一些3D基础,而我之前并没有接触过 ...

  10. Shell编程菜鸟基础入门笔记

    Shell编程基础入门     1.shell格式:例 shell脚本开发习惯 1.指定解释器 #!/bin/bash 2.脚本开头加版权等信息如:#DATE:时间,#author(作者)#mail: ...

随机推荐

  1. harbor 安装

    下载地址: https://github.com/goharbor/harbor/releases?page=1 下载了多个版本,发现仅v1.10.17版本支持GC清理,所以这里安装的v1.10.17 ...

  2. Abp.Zero 手机号免密登录验证与号码绑定功能的实现(二):改造Abp默认实现

    接下来我们重写原Abp的部分实现,来驳接手机号相关业务. 改造User类 重写PhoneNumber使得电话号码为必填项,和中国大陆手机号11位长度 public new const int MaxP ...

  3. open cv java 可以 对图片进行分析,得到数据。考试答题卡 2B铅笔涂黑嘎达 识别

    open cv java 可以 对图片进行分析,得到数据.考试答题卡 2B铅笔涂黑嘎达 识别

  4. B站Aimls的JavaFx教程目录合集

    B站里有时候不太好去找资源,用JS爬了下,整出标题和链接,方便后续查询某个知识点的使用! JavaFX视频教程第1课,hello world JavaFX视频教程第2课,application的启动方 ...

  5. My97DatePicker设置默认时间

    <%@ page language="java"  pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC ...

  6. JSF+EJB+JPA之整体思想

    序言: JSF+EJB+JPA 其实没有想象中的难,不过要做好应用以及在合适的地方建立应用,才是真正的难点. 好的技术在不合适的地方做了应用,那也只能是垃圾. 所以这个东西并不适合于太小规模的企业应用 ...

  7. Java线上诊断神器Arthas:常用命令详解!

    有关Arthas基本介绍.安装部署.arthas idea插件在上篇文章已经介绍过,这里就不在重述. 文章地址:Java诊断工具Arthas:开篇之watch实战 上篇重点讲了 watch 命令.这篇 ...

  8. Elastic实战:彻底解决spring-data-elasticsearch日期、时间类型数据读取报错问题

    0. 引言在使用spring-data-elasticsearch读取es中时间类型的数据时出现了日期转换报错,不少初学者会在这里困惑很久,所以今天我们专门来解读该问题的几种解决方案. 1. 问题分析 ...

  9. AI实用指南:5分钟搭建你自己的LLM聊天应用

    今天,我们将迅速着手搭建一个高效且富有创意的混元聊天应用,其核心理念可以用一个字来概括--快.在这个快节奏的时代,构建一个基础的LLM(Large Language Model,大型语言模型)聊天应用 ...

  10. FPGA中的速度优化

    FPGA中的速度优化 一.逻辑设计中的速度概念 逻辑设计速度相关的概念有三个:设计吞吐量.设计延时和设计时序.速度优化策略而言,吞吐量需要提高,延时应该降低,时序应该收敛(时序余量slave越大,收敛 ...