爬虫毕竟是在网页里面抓取数据的,因此前端那些东西没学过也要稍微懂点。HTML、CSS简单的语法,Xpath、正则表达式等等,需要有一些简单的基础。
Scrapy一个开源和协作的框架,其最初是为了页面抓取(更确切来说,网络抓取)所设计的,使用它可以快速、简单、可扩展的方式从网站中提取所需要的数据。但目前Scrapy的用途十分广泛,可用与如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(如: Amazon Associatates web services)或者统一的网络爬虫。
Scrapy就是爬虫界的django
- Scrapy框架类似于Django框架
(摘自Scrapy官方文档:docs.scrapy.org/en/latest/i…
| 组件 | 作用 |
|---|---|
| Scrapy Engine | 引擎,处理整个框架的数据流 |
| Scheduler | 调度器,接收引擎发过来的请求,将其排至队列中,当引擎再次请求时返回 |
| Downloader | 下载器,下载所有引擎发送的请求,并将获取的源代码返回给引擎,之后由引擎交给爬虫处理 |
| Spiders | 爬虫,接收并处理所有引擎发送过来的源代码,从中分析并提取item字段所需要的数据,并将需要跟进的url提交给引擎,再次进入调度器 |
| Item Pipeline | 管道,负责处理从爬虫中获取的Item,并进行后期处理 |
| Downloader Middlewares | 下载中间件,可以理解为自定义扩展下载功能的组件 |
| Spider Middlewares | Spider中间件,自定义扩展和操作引擎与爬虫之间通信的功能组件 |
在Scrapy中,数据流由执行引擎控制,流程如下:
scrapy的概念:Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架
scrapy框架的运行流程以及数据传递过程:
调度器把requests–>引擎–>下载中间件—>下载器
下载器发送请求,获取响应---->下载中间件---->引擎—>爬虫中间件—>爬虫
爬虫提取url地址,组装成request对象---->爬虫中间件—>引擎—>调度器
爬虫提取数据—>引擎—>管道
管道进行数据的处理和保存
scrapy框架的作用:通过少量代码实现快速抓取
掌握scrapy中每个模块的作用:
引擎(engine):负责数据和信号在不同模块间的传递 调度器(scheduler):实现一个队列,存放引擎发过来的request请求对象
下载器(downloader):发送引擎发过来的request请求,获取响应,并将响应交给引擎
爬虫(spider):处理引擎发过来的response,提取数据,提取url,并交给引擎
管道(pipeline):处理引擎传递过来的数据,比如存储
下载中间件(downloader middleware):可以自定义的下载扩展,比如设置代理ip
爬虫中间件(spider middleware):可以自定义request请求和进行response过滤
理解异步和非阻塞的区别:异步是过程,非阻塞是状态
scrapy -h
scrapy <command> -h
Global commands:
startproject #创建项目
genspider #创建爬虫程序
settings #如果是在项目目录下,则得到的是该项目的配置
runspider #运行一个独立的python文件,不必创建项目
shell #scrapy shell url地址 在交互式调试,如选择器规则正确与否
fetch #独立于程单纯地爬取一个页面,可以拿到请求头
view #下载完毕后直接弹出浏览器,以此可以分辨出哪些数据是ajax请求
version #scrapy version 查看scrapy的版本,scrapy version -v查看scrapy依赖库的版本
Project-only commands:
crawl #运行爬虫,必须创建项目才行,确保配置文件中ROBOTSTXT_OBEY = False
check #检测项目中有无语法错误
list #列出项目中所包含的爬虫名
parse #scrapy parse url地址 --callback 回调函数 #以此可以验证我们的回调函数是否正确
bench #scrapy bentch压力测试
startproject:创建一个新的 Scrapy 项目。genspider:创建一个新的爬虫程序。settings:显示一个 Scrapy 项目的配置信息。runspider:运行一个独立的 Python 文件作为爬虫,不需要创建项目。shell:进入 Scrapy 的交互式调试环境,可以检查选择器规则是否正确。fetch:单独请求一个页面,并获取响应结果。view:下载指定页面并在浏览器中打开,用于检查通过哪些请求获取数据。version:查看当前安装的 Scrapy 版本号。crawl:运行一个 Scrapy 爬虫,必须在项目目录下执行且确保配置文件中的 ROBOTSTXT_OBEY 设置为 False。check:检查项目中是否存在语法错误。list:列出项目中包含的所有爬虫名称。parse:使用回调函数解析给定的 URL,用于验证回调函数是否正确。bench:用于对 Scrapy 进行压力测试。scrapy startproject one



在Windows系统中,你可以使用tree命令来显示当前目录及其子目录中的文件结构:
# tree /F
在类Unix/Linux系统中,你可以使用tree命令来显示当前目录及其子目录中的文件结构,但需要先安装tree工具。如果没有安装,你可以使用ls命令来显示当前目录中的文件和目录:
# ls -R

| 文件 | 作用 |
|---|---|
| scrapy.cfg | 配置文件 |
| spiders | 存放你Spider文件,也就是你爬取的py文件 |
| items.py | 相当于一个容器,和字典较像 |
| middlewares.py | 定义Downloader Middlewares(下载器中间件)和Spider Middlewares(蜘蛛中间件)的实现 |
| pipelines.py | 定义Item Pipeline的实现,实现数据的清洗,储存,验证。 |
| settings.py | 全局配置 |
要在Scrapy中创建一个爬虫,你可以使用以下命令:
# scrapy genspider
其中,是你要创建的爬虫的名称,是你要开始爬取的起始URL。
scrapy genspider 命令创建一个新的爬虫时,你需要提供两个参数:
# scrapy genspider example http://example.com
# scrapy genspider jing http://www.baidu.com

import scrapy
class JingSpider(scrapy.Spider):
# 爬虫文件的唯一标识
name = "jing"
# 允许访问的域名
allowed_domains = ["www.baidu.com"]
# 起始 的 URL 列表 (重要)
# 列表内部的 url 都会被框架进行异步请求发送
start_urls = ["http://www.baidu.com"]
# 数据解析主函数:自动调用
# 调用的次数取决于 start_urls 列表内元素的个数
def parse(self, response):
# response : 表示的就是响应对象
print("response:::", response.text)
Scrapy 项目,而非通过文件启动scrapy crawl jing
settings.py 文件中添加指定配置项# 指定输出日志的类型:
LOG_LEVEL = 'ERROR'

ROBOTS协议ROBOTSTXT_OBEY = False
from scrapy.cmdline import execute
execute(['scrapy', 'crawl', '自定义爬虫文件名', "--nolog"])
| 表达式 | 描述 | 实例 |
|---|---|---|
| nodename | 选取nodename节点的所有子节点 | //div |
| / | 从根节点选取 | /div |
| // | 选取任意位置的节点,不考虑他们的位置 | //div |
| . | 选取当前节点 | ./div |
| … | 选取当前节点的父节点 | … |
| @ | 选取属性 | //@calss |
| 语法 | 说明 |
|---|---|
| artical | 选取所有artical元素的子节点 |
| /artical | 选取根元素artical |
| ./artical | 选取当前元素下的artical |
| …/artical | 选取父元素下的artical |
| artical/a | 选取所有属于artical的子元素a元素 |
| //div | 选取所有div 子元素,无论div在任何地方 |
| artical//div | 选取所有属于artical的div 元素,无论div元素在artical的任何位置 |
| //@class | 选取所有class属性 |
| a/@href | 选取a标签的href属性 |
| a/text() | 选取a标签下的文本 |
| string(.) | 解析出当前节点下所有文字 |
| string(…) | 解析出父节点下所有文字 |
| 语法 | 说明 |
|---|---|
| /artical/div[1] | 选取所有属于artical 子元素的第一个div元素 |
| /artical/div[last()] | 选取所有属于artical子元素的最后一个div元素 |
| /artical/div[last()-1] | 选取所有属于artical子元素的倒数第2个div元素 |
| /artical/div[position()❤️] | 选取所有属于artical子元素的前2个div元素 |
| //div[@class] | 选取所有拥有属性为class的div节点 |
| //div[@class=”main”] | 选取所有div下class属性为main的div节点 |
| //div[price>3.5] | 选取所有div下元素值price大于3.5的div节点 |