1.scrapy框架

1.1 安装scrapy

  1. pip3 install wheel
  2. 下载twisted http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
  3. 进入下载目录,执行 pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl
  4. pip3 install pywin32
  5. pip3 install scrapy

1.2 简单使用

scrapy创建需要在终端执行命令

  • scrapy startproject proName 创建项目
  • cd proNme 进入项目文件夹
  • scrapy genspider spiderName www.xxx.com 创建一个爬虫文件

1.3 配置文件

  • 不遵从robots协议

    # Obey robots.txt rules
    ROBOTSTXT_OBEY = False
  • 进行UA伪装

    USER_AGENT = '浏览器USER_AGENT'
  • 进行日志等级设定:

    LOG_LEVEL = 'ERROR'

1.4 使用方法

import scrapy
class FirstSpider(scrapy.Spider):
# 爬虫文件的名称:爬虫文件的唯一标识(在spiders子目录下是可以创建多个爬虫文件)
name = 'first'
# 允许的域名,一般注释掉
allowed_domains = ['www.baidu.com']
# 起始的url列表:列表中存放的url会被scrapy自动的进行请求发送
start_urls = ['https://www.baidu.com/', 'https://www.sogou.com/'] # 用作于数据解析:将start_urls列表中对应的url请求成功后的响应数据进行解析
def parse(self, response):
print(response)
  • 项目启动命令

    • scrapy crawl pro_name

1.5 持久化存储

  • 基于终端指令:

    • 特性:只可以将parse方法的返回值存储到本地的磁盘文件中
    • 存储指令: scrapy crawl spiderName -o filePath
    class XiaopapaSpider(scrapy.Spider):
    name = 'qiubai'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['https://www.qiushibaike.com/text/'] # 基于终端指令的持久化存储操作
    def parse(self, response):
    div_list = response.xpath('//*[@id="content-left"]/div')
    all_data = []
    for div in div_list:
    # scrapy中的xpath返回的列表的列表元素一定是Selector对象,我们最终想要的解析的数据一定是存储在该对象中
    # extract()将Selector对象中data参数的值取出
    # author = div.xpath('./div[1]/a[2]/h2/text()')[0].extract() # 取第一个
    author = div.xpath('./div[1]/a[2]/h2/text()').extract_first() # 也是取第一个
    # 列表直接调用extract表示的是将extract作用到每一个列表元素中
    content = div.xpath('./a[1]/div/span//text()').extract()
    content = ''.join(content)
    dic = {'author': author,
    'content': content }
    all_data.append(dic)
    return all_data # response.xpath("xpath 路径") 返回的列表的列表元素是Selector对象,数据存在该对象当中
    # extract()将Selector对象中data参数的值取出
    # .extract_first() # 取第一个值
    # 列表直接调用extract表示的是将extract作用到每一个列表元素中,返回的是一个列表

  • 基于管道:实现流程

    1.数据解析

    2.在item类中定义相关的属性

    3.将解析的数据存储或者封装到一个item类型的对象(items文件中对应类的对象)

    4.向管道提交item

    5.在管道文件的process_item方法中接收item进行持久化存储

    6.在配置文件中开启管道

    # 管道中需要注意的细节:
    - 配置文件中开启管道对应的配置是一个字典,字典中的键值表示的就是某一个管道
    - 在管道对应的源文件中其实可以定义多个管道类。一个管道类对应的是一种形式的持久化存储
    - 在process_item方法中的return item表示的是将item提交给下一个即将被执行的管道类
    - 爬虫文件通过yield item只可以将item提交给第一个(优先级最高)被执行的管道
  • 将同一份数据持久化到不同的平台中

    • 分析:

      • 1.管道文件中的一个管道类负责数据的一种形式的持久化存储
      • 2.爬虫文件向管道提交的item只会提交给优先级最高的那一个管道类
      • 3.在管道类的process_item中的return item表示的是将当前管道接收的item返回/提交给

        下一个即将被执行的管道类
    # 基于管道的持久化存储
    # 爬虫.py文件,
    def parse(self, response):
    div_list = response.xpath('//*[@id="content-left"]/div')
    all_data = []
    for div in div_list:
    #scrapy中的xpath返回的列表的列表元素一定是Selector对象,我们最终想要的解析的
    #数据一定是存储在该对象中
    #extract()将Selector对象中data参数的值取出
    # author = div.xpath('./div[1]/a[2]/h2/text()')[0].extract()
    author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()
    #列表直接调用extract表示的是将extract作用到每一个列表元素中
    content = div.xpath('./a[1]/div/span//text()').extract()
    content = ''.join(content)
    #将解析的数据存储到item对象
    item = QiubaiproItem()
    item['author'] = author
    item['content'] = content
    #将item提交给管道
    yield item #item一定是提交给了优先级最高的管道类
    • items.py文件
    # items.py文件
    class QiubaiproItem(scrapy.Item):
    author = scrapy.Field() #Field可以将其理解成是一个万能的数据类型
    content = scrapy.Field()
    • pipelines.py文件

      • 存储到不同的数据平台中
    # pipelines.py文件
    #存储到文件中
    class QiubaiproPipeline(object):
    fp = None
    def open_spider(self,spider): # 重写父类方法,只会执行一次,打开文件
    print('开始爬虫!')
    self.fp = open('qiushibaike.txt','w',encoding='utf-8') #使用来接收爬虫文件提交过来的item,然后将其进行任意形式的持久化存储
    #参数item:就是接收到的item对象
    #该方法每接收一个item就会调用一次
    def process_item(self, item, spider):
    author = item['author']
    content= item['content'] self.fp.write(author+':'+content+'\n')
    return item #item是返回给了下一个即将被执行的管道类 def close_spider(self,spider): # 重写父类方法,只会执行一次,关闭文件
    print('结束爬虫!')
    self.fp.close() #负责将数据存储到mysql
    class MysqlPL(object):
    conn = None
    cursor = None
    def open_spider(self,spider):
    self.conn = pymysql.Connect(host='127.0.0.1',
    port=3306,
    user='root',
    password='123',
    db='spider',
    charset='utf8')
    print(self.conn)
    def process_item(self,item,spider):
    author = item['author']
    content = item['content']
    sql = 'insert into qiubai values ("%s","%s")'%(author,content)
    self.cursor = self.conn.cursor()
    try:
    self.cursor.execute(sql)
    self.conn.commit()
    except Exception as e:
    print(e)
    self.conn.rollback()
    return item
    def close_spider(self,spider):
    self.cursor.close()
    self.conn.close() # 存到redis
    class RedisPL(object):
    conn = None
    def open_spider(self,spider):
    self.conn = Redis(host='127.0.0.1',port=6379)
    print(self.conn)
    def process_item(self,item,spider):
    self.conn.lpush('all_data',item)
    #注意:如果将字典写入redis报错:pip install -U redis==2.10.6
    • settings文件

      • 注册定义的管道
    ITEM_PIPELINES = {
    'qiubaiPro.pipelines.QiubaiproPipeline': 300, # 300表示的是优先级,数字越小,优先级就越大
    'qiubaiPro.pipelines.MysqlPL': 301,
    'qiubaiPro.pipelines.RedisPL': 302,
    }

1.6 发送请求

1.6.1 自动请求发送:

def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(url,callback=self.parse)

1.6.2 手动发送请求:

  • 在scrapy中如何进行手动请求发送(GET)

    • 使用场景:爬取多个页码对应的页面源码数据
    • yield scrapy.Request(url,callback)
  • 在scrapy中如何进行手动请求发送(POST)

    data = { #post请求的请求参数

    'kw':'aaa'

    }

    yield scrapy.FormRequest(url,formdata=data,callback)
#将多个页码对应的页面数据进行爬取和解析的操作

url = 'https://www.qiushibaike.com/text/page/%d/'#通用的url模板
pageNum = 1
#parse第一次调用表示的是用来解析第一页对应页面中的段子内容和作者
def parse(self, response):
div_list = response.xpath('//*[@id="content-left"]/div')
all_data = []
for div in div_list:
author = div.xpath('./div[1]/a[2]/h2/text()').extract_first()
# 列表直接调用extract表示的是将extract作用到每一个列表元素中
content = div.xpath('./a[1]/div/span//text()').extract()
content = ''.join(content) # 将解析的数据存储到item对象
item = QiubaiproItem()
item['author'] = author
item['content'] = content # 将item提交给管道
yield item # item一定是提交给了优先级最高的管道类 if self.pageNum <= 5:
self.pageNum += 1
new_url = format(self.url%self.pageNum)
#手动请求(get)的发送
yield scrapy.Request(new_url,callback=self.parse) # 递归调用parse方法

1.7 scrapy五大核心组件的工作流程

  • 引擎(Scrapy)

    • 用来处理整个系统的数据流处理, 触发事务(框架核心)
  • 调度器(Scheduler)
    • 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
  • 下载器(Downloader)
    • 用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
  • 爬虫(Spiders)
    • 爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
  • 项目管道(Pipeline)
    • 负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。

scrapy--使用案例的更多相关文章

  1. 爬虫框架Scrapy之案例三图片下载器

    items.py class CoserItem(scrapy.Item): url = scrapy.Field() name = scrapy.Field() info = scrapy.Fiel ...

  2. 爬虫框架Scrapy之案例二

    新浪网分类资讯爬虫 爬取新浪网导航页所有下所有大类.小类.小类里的子链接,以及子链接页面的新闻内容. 效果演示图: items.py import scrapy import sys reload(s ...

  3. 爬虫框架Scrapy之案例一

    阳光热线问政平台 http://wz.sun0769.com/index.php/question/questionType?type=4 爬取投诉帖子的编号.帖子的url.帖子的标题,和帖子里的内容 ...

  4. 爬虫——Scrapy框架案例二:阳光问政平台

    阳光热线问政平台 URL地址:http://wz.sun0769.com/index.php/question/questionType?type=4&page= 爬取字段:帖子的编号.投诉类 ...

  5. 爬虫——Scrapy框架案例一:手机APP抓包

    以爬取斗鱼直播上的信息为例: URL地址:http://capi.douyucdn.cn/api/v1/getVerticalRoom?limit=20&offset=0 爬取字段:房间ID. ...

  6. 爬虫 (6)- Scrapy 实战案例 - 爬取不锈钢的相关钢卷信息

    超详细创建流程及思路 一. 新建项目 1.创建文件夹,然后在对应文件夹创建一个新的python项目 2.点击Terminal命令行窗口,运行下面的命令创建scrapy项目 scrapy startpr ...

  7. 爬虫之scrapy简单案例之猫眼

    在爬虫py文件下 class TopSpider(scrapy.Spider): name = 'top' allowed_domains = ['maoyan.com'] start_urls = ...

  8. Scrapy爬虫案例 | 数据存储至MySQL

    首先,MySQL创建好数据库和表 然后编写各个模块 item.py import scrapy class JianliItem(scrapy.Item): name = scrapy.Field() ...

  9. Scrapy爬虫案例 | 数据存储至MongoDB

    豆瓣电影TOP 250网址 要求: 1.爬取豆瓣top 250电影名字.演员列表.评分和简介 2.设置随机UserAgent和Proxy 3.爬取到的数据保存到MongoDB数据库  items.py ...

  10. scrapy爬虫案例:用MongoDB保存数据

    用Pymongo保存数据 爬取豆瓣电影top250movie.douban.com/top250的电影数据,并保存在MongoDB中. items.py class DoubanspiderItem( ...

随机推荐

  1. 【C# 线程】线程局部存储(TLS) 实战部分 ThreadStatic|LocalDataStoreSlot|ThreadLocal<T>

    往袋子里面装苹果 错误案例示范 关于C#多线程的文章,大部分都在讨论线程的起停或者是多线程同步问题.多线程同步就是在不同线程中访问同一个变量(一般是线程工作函数外部的变量),众所周知在不使用线程同步的 ...

  2. 【windows 操作系统】进程

    前言 Windows的内部实现也近似于"一切皆文件"的思想,当然,这一切都只在内核里才有,下载一个WinObj这软件就可以看到,Windows上各种设备.分区.虚拟对象都是挂载到根 ...

  3. MySQL 学习笔记(二)MVCC 机制

    之前在讲 MySQL 事务隔离性提到过,对于写操作给读操作的影响这种情形下发生的脏读.不可重复读.虚读问题.是通过MVCC 机制来进行解决的,那么MVCC到底是如何实现的,其内部原理是怎样的呢?我们要 ...

  4. WPS:查看隐藏文字与分页符……

    文件->选项->视图

  5. 前端vue下载文件时blob返回流中怎么获取文件名

    我很久之前写了一篇前端vue利用blob对象下载文件,有些人私信我,如果后端返回流失败,给出的json对象该怎么获得?前端获取的流怎么能获取原文件名?其实在那篇文章之后,我就已经针对这两个问题进行了优 ...

  6. 开机弹出一下Visual Studio Just-In-Time对话框的问题

    开机弹出一下Visual Studio Just-In-Time对话框 开机弹出一下Visual studio just-in-time对话框,出现一下问题,且点击确定后又弹出第二个对话框, 解决方法 ...

  7. JZ-062-二叉查找树的第 K 个结点

    二叉查找树的第 K 个结点 题目描述 给定一棵二叉搜索树,请找出其中的第k小的结点. 题目链接: 二叉查找树的第 K 个结点 代码 /** * 标题:二叉查找树的第 K 个结点 * 题目描述 * 给定 ...

  8. react 也就这么回事 05 —— 组件 & Props

    什么是组件:用来实现局部功能的可复用代码片段 比如很多界面会用到"分页"功能,因此可以将它封装成独立的组件 这样用到分页的界面只需引入该组件而不必重新写代码 1 定义组件 在 Re ...

  9. php 23种设计模型 - 享元模式

    享元模式 享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. ...

  10. 从刘维尔方程到Velocity-Verlet算法

    技术背景 我们说分子动力学模拟是一个牛顿力学的过程,在使用量子化学的手段或者深度学习的方法或者传统的力场方法,去得到某个时刻某个位置的受力之后,就可以获取下一步的整个系统的状态信息.这个演化的过程所使 ...