爬虫之scrapy框架(一)

2020-03-19 15:42:17 浏览数 (1)

目录

  • 一、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:

  1. The Engine gets the initial Requests to crawl from the Spider.
  2. The Engine schedules the Requests in the Scheduler and asks for the next Requests to crawl.
  3. The Scheduler returns the next Requests to the Engine.
  4. The Engine sends the Requests to the Downloader, passing through the Downloader Middlewares (see process_request()).
  5. 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()).
  6. 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()).
  7. 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()).
  8. The Engine sends processed items to Item Pipelines, then send processed Requests to the Scheduler and asks for possible next Requests to crawl.
  9. The process repeats (from step 1) until there are no more requests from the Scheduler.

Components:

  1. 引擎(EGINE) 引擎负责控制系统所有组件之间的数据流,并在某些动作发生时触发事件。有关详细信息,请参见上面的数据流部分。
  2. 调度器(SCHEDULER) 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
  3. 下载器(DOWLOADER) 用于下载网页内容, 并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的
  4. 爬虫(SPIDERS) SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求
  5. 项目管道(ITEM PIPLINES) 在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作
  6. 下载器中间件(Downloader Middlewares) 位于Scrapy引擎和下载器之间,主要用来处理从EGINE传到DOWLOADER的请求request,已经从DOWNLOADER传到EGINE的响应response,你可用该中间件做以下几件事
    1. process a request just before it is sent to the Downloader (i.e. right before Scrapy sends the request to the website);
    2. change received response before passing it to a spider;
    3. send a new Request instead of passing received response to a spider;
    4. pass response to a spider without fetching a web page;
    5. silently drop some requests.
  7. 爬虫中间件(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,
}

0 人点赞