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"]+"\n") 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即可。