目录
- 一、scrapy简介,架构介绍
- 1.1scrapy简介
- 1.2架构介绍
- 1.3安装
- 命令行工具
- 二、scrapy创建项目及介绍
- 2.1项目创建
- 2.2目录介绍
- 2.3settings介绍
- 三、scrapy的数据解析(重点)
- 3.1css选择器
- 3.2xpath选择
- 四、scrapy的持久化存储(重点)
- 4.1持久化到文件
- 4.2持久化到数据库
一、scrapy简介,架构介绍
1.1scrapy简介
Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。但目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。
Scrapy 是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架。因此Scrapy使用了一种非阻塞(又名异步)的代码来实现并发。整体架构大致如下
1.2架构介绍
The data flow in Scrapy is controlled by the execution engine, and goes like this:
- The Engine gets the initial Requests to crawl from the Spider.
- The Engine schedules the Requests in the Scheduler and asks for the next Requests to crawl.
- The Scheduler returns the next Requests to the Engine.
- The Engine sends the Requests to the Downloader, passing through the Downloader Middlewares (see
process_request()
). - Once the page finishes downloading the Downloader generates a Response (with that page) and sends it to the Engine, passing through the Downloader Middlewares (see
process_response()
). - The Engine receives the Response from the Downloader and sends it to the Spider for processing, passing through the Spider Middleware (see
process_spider_input()
). - The Spider processes the Response and returns scraped items and new Requests (to follow) to the Engine, passing through the Spider Middleware (see
process_spider_output()
). - The Engine sends processed items to Item Pipelines, then send processed Requests to the Scheduler and asks for possible next Requests to crawl.
- The process repeats (from step 1) until there are no more requests from the Scheduler.
Components:
- 引擎(EGINE) 引擎负责控制系统所有组件之间的数据流,并在某些动作发生时触发事件。有关详细信息,请参见上面的数据流部分。
- 调度器(SCHEDULER) 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
- 下载器(DOWLOADER) 用于下载网页内容, 并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的
- 爬虫(SPIDERS) SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求
- 项目管道(ITEM PIPLINES) 在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作
- 下载器中间件(Downloader Middlewares)
位于Scrapy引擎和下载器之间,主要用来处理从EGINE传到DOWLOADER的请求request,已经从DOWNLOADER传到EGINE的响应response,你可用该中间件做以下几件事
- process a request just before it is sent to the Downloader (i.e. right before Scrapy sends the request to the website);
- change received response before passing it to a spider;
- send a new Request instead of passing received response to a spider;
- pass response to a spider without fetching a web page;
- silently drop some requests.
- 爬虫中间件(Spider Middlewares) 位于EGINE和SPIDERS之间,主要工作是处理SPIDERS的输入(即responses)和输出(即requests)
1.3安装
代码语言:javascript复制windows/mac/linux:pip3 install scrapy
#windows优先采用上面的方式进行安装,如果报错再采用下面的方式
windwos:
-pip3 install scrapy(大部分同学直接是可以的)
-如果上面不行
-pip3 install wheel (xxx.whl文件安装模块)
-下载pywin32:两种方式:1 pip3 install pywin32 2 下一个exe安装https://sourceforge.net/projects/pywin32/files/pywin32/
-下载twisted的wheel文件:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted 下载完是一个xxx.whl文件
-执行pip3 install 下载目录Twisted-17.9.0-cp36-cp36m-win_amd64.whl
命令行工具
代码语言:javascript复制#1 查看帮助
scrapy -h
scrapy <command> -h
#2 有两种命令:其中Project-only必须切到项目文件夹下才能执行,而Global的命令则不需要
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 #列出项目中所包含的爬虫名
edit #编辑器,一般不用
parse #scrapy parse url地址 --callback 回调函数 #以此可以验证我们的回调函数是否正确
bench #scrapy bentch压力测试
二、scrapy创建项目及介绍
2.1项目创建
代码语言:javascript复制# 通过命令创建项目,到指定的文件夹下
# 创建项目(django中创建项目)
scrapy startproject 项目名字
# 创建爬虫(django中创建app)在spiders文件夹下创建一个py文件,一个py文件就是一个爬虫(不要注册,没有注册一说)
scrapy genspider 爬虫名字 爬取的地址
scrapy genspider chouti dig.chouti.com
# 打开项目,pycharm打开
# 运行爬虫 命令行下
scrapy crawl 爬虫名字
scrapy crawl 爬虫名字 --nolog # 不打印日志
# 运行爬虫 py文件
在项目目录下创建一个py文件,假设叫main.py,点击右键执行即可执行爬虫,等同于命令
from scrapy.cmdline import execute
execute(['scrapy','crawl','chouti'])
2.2目录介绍
代码语言:javascript复制-scarpyfirst 项目名
-scrapy.cfg 上线相关的
-scrapyfirst 文件夹
-spiders文件夹 :所有的爬虫写在这里面
-chouti.py :一个py文件就是一个爬虫(类似于django的app)
-items.py :配合管道,做数据存储(类似于django中models.py 写一个个的模型类)
-middlewares.py :中间件(爬虫中间件,下载中间件都写在这里面)
-pipelines.py :管道,持久化相关,数据存储卸载这
-settings.py :配置文件相关
2.3settings介绍
一般爬虫项目需要进行下面的配置,关于settings的详细介绍见下一篇scrapy文章。
代码语言:javascript复制#配置文件全是大写
ROBOTSTXT_OBEY = True #是否遵循爬虫协议,如果是true,基本上网站都爬不了,遵循要爬取网站的爬虫协议,一般设置成false
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'
LOG_LEVEL='ERROR' # 只打印错误信息
三、scrapy的数据解析(重点)
关于详细的css、xpath选择器介绍请看上一篇文章,这里只介绍属性和文本的选择
3.1css选择器
代码语言:javascript复制css选择
response.css('标签').extract() #取所有标签
response.css('标签').extract_first()#获取一个标签 用的比较多
response.css('标签::attr(属性)').extract_first() #选取标签的属性
response.css('标签::text').extract_first()#选取标签内的文本
response.css('a::attr(href)').extract_first()
response.css('p::text').extract_first()
3.2xpath选择
代码语言:javascript复制response.xpath('').extract_first() #获取一个标签 用的比较多
response.xpath('./div/div/div[1]/a/text()').extract_first()#获取标签内文本
response.xpath('./@属性').extract_first()#获取标签内属性
四、scrapy的持久化存储(重点)
持久化存储有两种方式:
第一种:通过命令:scrapy crawl chout -o aa.csv (用的比较少)需要在parser解析方法中返回列表套字典的格式。 第二种:通过管道方式,大部分使用这种方式
4.1持久化到文件
在pipelines.py中,open_spider打开文件,process_item里写入文件,close_spider关闭文件。执行的步骤是先执行open_spider,然后执行process_item将爬取到的所有数据写入,所有的爬虫结束执行close_spider。
代码语言:javascript复制class ChoutiPipeline(object):
def open_spider(self,spider):
print('我开了')
self.f=open('a.txt','w')
def process_item(self, item, spider):
self.f.write(item['desc'] item['img_url'])
self.f.write('n')
return item
def close_spider(self,spider):
self.f.close()
print("我关了")
4.2持久化到数据库
在4.1版本上稍作改变将文本写入改为写入数据库就行了,代码如下:
代码语言:javascript复制import pymysql
# 存文件
class ChoutiMysqlPipeline(object):
def open_spider(self, spider):
# autocommit=True 表示自动提交
self.conn=pymysql.connect(host='127.0.0.1', user='root',
password="123",database='chouti', port=3306)
def process_item(self, item, spider):
cursor=self.conn.cursor()
sql="insert into article (`desc`,img_url) values ('%s','%s')"%(item['desc'],item['img_url'])
cursor.execute(sql)
self.conn.commit()#不要忘了提交
def close_spider(self, spider):
self.conn.close()
settings.py中进行如下配置
代码语言:javascript复制ITEM_PIPELINES = {
'scrapyfirst.pipelines.ChoutiPipeline': 300,
'scrapyfirst.pipelines.ChoutiMysqlPipeline': 302,
}