Scrapy数据解析和持久化

Posted sun-10387834

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scrapy数据解析和持久化相关的知识,希望对你有一定的参考价值。

Scrapy框架的使用
    - pySpider
- 什么是框架?
    - 就是一个具有很强通用性且集成了很多功能的项目模板(可以被应用在各种需求中)
- scrapy集成好的功能:
    - 高性能的数据解析操作(xpath)
    - 高性能的数据下载
    - 高性能的持久化存储
    - 中间件
    - 全栈数据爬取操作
    - 分布式:redis
    - 请求传参的机制(深度爬取)
    - scrapy中合理的应用selenium
- 环境的安装
          a. pip3 install wheel

            b. 下载twisted http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

            c. 进入下载目录,执行 pip3 install Twisted?17.1.0?cp35?cp35m?win_amd64.whl

            d. pip3 install pywin32

             e. pip3 install scrapy

- 创建工程
    - scrapy startproject ProName
    - cd ProName
    - scrapy genspider spiderName www.xxx.com :创建爬虫文件
    - 执行:scrapy crawl spiderName
    - settings:
        - 不遵从robots协议
        - UA伪装
        - LOG_LEVEL = ERROR
        - LOG_FILE = logging.log

 - scrapy的数据解析
    - extract():列表是有多个列表元素
    - extract_first():列表元素只有单个
 - scrapy的持久化存储
    - 基于终端指令:
        - 只可以将parse方法的返回值存储到磁盘文件中
        - scrapy crawl first -o file.csv
    - 基于管道:pipelines.py
        - 编码流程:
            - 1.数据解析
            - 2.在item的类中定义相关的属性
            - 3.将解析的数据存储封装到item类型的对象中.item[p]
            - 4.将item对象提交给管道
            - 5.在管道类中的process_item方法负责接收item对象,然后对item进行任意形式的持久化存储
            - 6.在配置文件中开启管道
         - 细节补充:
            - 管道文件中的一个管道类表示将数据存储到某一种形式的平台中。
            - 如果管道文件中定义了多个管道类,爬虫类提交的item会给到优先级最高的管道类。
            - process_item方法的实现中的return item的操作表示将item传递给下一个即将被执行的管道类

实例:抓取虎牙直播名称,直播者昵称和热度

第一种持久化方式(基于终端):

hy.py实例代码:

# -*- coding: utf-8 -*-
import scrapy
class HySpider(scrapy.Spider):
    name = hy
    # allowed_domains = [‘www.xx.com‘]
    start_urls = [https://www.huya.com/g/3203]

    def parse(self, response):
        li_list=response.xpath(//*[@id="js-live-list"]/li)
        data=[]
        for li in li_list:
            title=li.xpath("./a[2]/text()").extract_first()
            nick=li.xpath("./span/span[1]/i/text()").extract_first()
            hot=li.xpath("./span/span[2]/i[2]/text()").extract_first()
            dic={"title":title,"nick":nick,"hot":hot}
            data.append(dic)
        return data

在pycharm终端输入命令:scrapy crawl hy -o huya.csv 回车执行即可。

第二种持久化方式(基于管道):

hy.py代码:

# -*- coding: utf-8 -*-
import scrapy
from huya.items import HuyaItem
class HySpider(scrapy.Spider):
    name = hy
    # allowed_domains = [‘www.xx.com‘]
    start_urls = [https://www.huya.com/g/3203]

    def parse(self, response):
        li_list=response.xpath(//*[@id="js-live-list"]/li)
        # data=[]*
        for li in li_list:
            title=li.xpath("./a[2]/text()").extract_first()
            nick=li.xpath("./span/span[1]/i/text()").extract_first()
            hot=li.xpath("./span/span[2]/i[2]/text()").extract_first()
            item=HuyaItem()
            item["title"]=title
            item["nick"]=nick
            item["hot"]=hot
            yield item
            # dic={"title":title,"nick":nick,"hot":hot}*
        #     data.append(dic)*
        # return data*

item类代码:

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy

class HuyaItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()
    nick = scrapy.Field()
    hot = scrapy.Field()

pipe类代码(同步实例化到本地和mysql中):

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don‘t forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import pymysql

class HuyaPipeline(object):
    def open_spider(self,spider):
        print("open_spider start work...")
        self.fp=open("huya.txt","w",encoding="utf-8")
    def process_item(self, item, spider):
        self.fp.write(item["title"]+"--"+item["nick"]+"--"+item["hot"]+"
")
        print(item["title"]+":持久化完毕...")
        return item
    def close_spider(self,spider):
        print("close_spider end work...")
        self.fp.close()

class mysqlPipeline(object):
    def open_spider(self,spider):
        print("open_spider start work...")
        self.conn=pymysql.Connect(host="127.0.0.1",port=3306,user="root",password="root",db="Spider",charset="utf8")
    def process_item(self, item, spider):
        sql="insert into huya values (‘%s‘,‘%s‘,‘%s‘)"%(item["title"],item["nick"],item["hot"])
        self.cursor=self.conn.cursor()
        try:
            self.cursor.execute(sql)
            self.conn.commit()
        except Exception as e:
            self.conn.rollback()
        return item
    def close_spider(self,spider):
        print("close_spider end work...")

setting中需要修改:

ITEM_PIPELINES = {
    huya.pipelines.HuyaPipeline: 300,
    huya.pipelines.mysqlPipeline: 301
}

**如果想要同步持久化到redis中只需要在pipe中添加类:

class RedisPipeLine(object):
    conn = None
    def open_spider(self,spider):
        self.conn = Redis(host=127.0.0.1,port=6379)
    def process_item(self,item,spider):
        self.conn.lpush(huyaList,item)
        return item

**然后修改setting中的ITEM_PIPELINES即可。

以上是关于Scrapy数据解析和持久化的主要内容,如果未能解决你的问题,请参考以下文章

0 scrapy架构介绍1 scrapy解析数据2 settings相关配置,提高爬取效率3 持久化方案 4 全站爬取cnblogs文章

scrapy框架之递归解析和post请求

爬虫学习 12.scrapy框架之递归解析和post请求

scrapy框架之递归解析和post请求

爬虫之scrapy框架

Scrapy框架基础应用和持久化存储