Scrapy 基础入门
0x01 框架概述
Scrapy 是基于 Python 的一个非常流行的网络爬虫框架,可以用来抓取 Web 站点并从页面中提取结构化的数据
(1)核心组件
- 引擎:用来控制整个系统的数据处理流程
- 调度器:从引擎接收请求并排序列入队列,并在引擎发出请求后返还
- 下载器:抓取网页并将网页内容返还给蜘蛛
- 蜘蛛程序:蜘蛛是用户自定义的用来解析网页并抓取特定 URL 的类
- 数据管道:处理蜘蛛从网页中抽取的数据条目
- 中间件:介于引擎和其他组件的钩子框架,提供自定义的代码来拓展 Scrapy 的功能
(2)工作流程
- 引擎问询蜘蛛需要处理的网站,并让蜘蛛交出第一个需要处理的 URL
- 引擎让调度器将需要处理的 URL 放入队列
- 引擎从调度中获取需要开始爬取的页面
- 调度将下一个需要爬取的 URL 返回到引擎,引擎将该 URL 通过下载中间件发送到下载器
- 当网页被下载器下载完成后,响应内容通过下载中间件发送到引擎;下载失败则引擎会通知调度记录并稍后重新下载该 URL
- 引擎收到下载器的响应并通过蜘蛛中间件发送到蜘蛛进行处理
- 蜘蛛处理响应并返回爬取到的数据条目,此外还要将需要跟进的新的 URL 发送给引擎
- 引擎将抓取到的数据条目送入数据管道,把新的 URL 发送给调度器放入队列中
0x02 第一个程序
(1)创建项目
a. 命令行
使用命令
pip install scrapy
安装 Scrapycssselect == 1.1.0
parsel == 1.6.0
使用命令
scrapy startproject demo
创建项目 Demo在项目目录下,使用命令
scrapy genspider douban movie.douban.com
创建蜘蛛程序项目目录如下:
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 基础入门的更多相关文章
- 0.Python 爬虫之Scrapy入门实践指南(Scrapy基础知识)
目录 0.0.Scrapy基础 0.1.Scrapy 框架图 0.2.Scrapy主要包括了以下组件: 0.3.Scrapy简单示例如下: 0.4.Scrapy运行流程如下: 0.5.还有什么? 0. ...
- [转]Scrapy简单入门及实例讲解
Scrapy简单入门及实例讲解 中文文档: http://scrapy-chs.readthedocs.io/zh_CN/0.24/ Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用 ...
- Scrapy爬虫入门系列3 将抓取到的数据存入数据库与验证数据有效性
抓取到的item 会被发送到Item Pipeline进行处理 Item Pipeline常用于 cleansing HTML data validating scraped data (checki ...
- Python3零基础入门学习视频+源码+课件+习题-小甲鱼
目录 1. 介绍 2. 目录 3. 下载地址 1. 介绍 适用人群 完全零基础入门,不需要任何前置知识. 课程概述 本系列教程面向零基础的同学,是一个深入浅出,通俗易懂的Python3视频教程. 前半 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- 「译」JUnit 5 系列:基础入门
原文地址:http://blog.codefx.org/libraries/junit-5-basics/ 原文日期:25, Feb, 2016 译文首发:Linesh 的博客:JUnit 5 系列: ...
- .NET正则表达式基础入门
这是我第一次写的博客,个人觉得十分不容易.以前看别人写的博客文字十分流畅,到自己来写却发现十分困难,还是感谢那些为技术而奉献自己力量的人吧. 本教程编写之前,博主阅读了<正则指引>这本入门 ...
- 从零3D基础入门XNA 4.0(2)——模型和BasicEffect
[题外话] 上一篇文章介绍了3D开发基础与XNA开发程序的整体结构,以及使用Model类的Draw方法将模型绘制到屏幕上.本文接着上一篇文章继续,介绍XNA中模型的结构.BasicEffect的使用以 ...
- 从零3D基础入门XNA 4.0(1)——3D开发基础
[题外话] 最近要做一个3D动画演示的程序,由于比较熟悉C#语言,再加上XNA对模型的支持比较好,故选择了XNA平台.不过从网上找到很多XNA的入门文章,发现大都需要一些3D基础,而我之前并没有接触过 ...
- Shell编程菜鸟基础入门笔记
Shell编程基础入门 1.shell格式:例 shell脚本开发习惯 1.指定解释器 #!/bin/bash 2.脚本开头加版权等信息如:#DATE:时间,#author(作者)#mail: ...
随机推荐
- 【转载】Java并发之AQS详解
一.概述 谈到并发,不得不谈ReentrantLock:而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)! 类如其名,抽象的队列式的同步器,AQ ...
- book 电子书转换 在线工具
https://convertio.co/download/911d3a3f39db0b2e39ed6e3c8acb31f6be786a/ Convertio
- 二: sql模式(sql_mode)
# sql_mode 1 介绍 sql_mode 会影响 MySQL支持的SQL语法以及它执行的数据验证检查.通过设置sql_mode,可以完成不同严格程度 的数据校验,有效地保障数据准确性. MyS ...
- Cordova下载文件,监听进度,退出疯狂报错
如题. 报错如下: W/cr_AwContents: Application attempted to call on a destroyed WebView java.lang.Throwable ...
- C语言中的rand()函数实例分析
一 前记: c语言中需要用到随机值得时候,每次都自己写,这样太浪费效率了,这次遇到了一个经典的代码,就珍藏起来吧. 二 实例分析: 1 #include <stdio.h> 2 3 int ...
- Java递归实现全排列改进(二)---利用ArrayList实现去重
import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Test{ priv ...
- Java线上诊断神器Arthas:常用命令详解!
有关Arthas基本介绍.安装部署.arthas idea插件在上篇文章已经介绍过,这里就不在重述. 文章地址:Java诊断工具Arthas:开篇之watch实战 上篇重点讲了 watch 命令.这篇 ...
- vim的使用进步
vim的使用进步 1.如果遇到命令行中无法退出的 狂按esc按键 或者也可以使用v模式下切换一下,之后按esc 保存退出 保存退出--:wq 保存:w 不保存退出:q! i--插入模式 v- 可视化模 ...
- Welcome to YARP - 1.认识 YARP 并构建反向代理服务
目录 Welcome to YARP - 1.认识YARP并搭建反向代理服务 Welcome to YARP - 2.配置功能 Welcome to YARP - 3.负载均衡 Welcome to ...
- 一天涨 23k Star 的开源项目「GitHub 热点速览」
在 GitHub 上做过开源项目的小伙伴,可能都经历过截图自己项目 100 Star.1000 Star 的时刻,但有些时候事情发生的太快来不及截图,因为可能一觉醒来就破万了.这件事看似有些天方夜谭 ...