栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

爬取数据不保存,就是耍流氓(3)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

爬取数据不保存,就是耍流氓(3)

目录
  • 前言
  • Items
  • Pipelines
  • 瞎比比
前言

OK,通过签名两篇文章《[爬虫利器初体验(1)]》《[听说你的爬虫又被封了?(2)]》,我们初体验也过了,爬虫代码健壮性也升级为 PLUS 了。都分析到这个地步了,是不是感觉还少了点什么?对,我们还没保存数据呀?不保存,这不是瞎忙活吗?

Items

item 是我们保存数据的容器,其类似于 python 中的字典。使用 item 的好处在于: **Item 提供了额外保护机制来避免拼写错误导致的未定义字段错误。**且看栗子:

import scrapy
class Doubantop250Item(scrapy.Item):
    title = scrapy.Field()  # 电影名字
    star = scrapy.Field()  # 电影评分
    quote = scrapy.Field()  # 脍炙人口的一句话
    movieInfo = scrapy.Field()  # 电影的描述信息,包括导演、主演、电影类型
Pipelines

pipelines.py 一般我们用于保存数据,其方法的一些介绍如下图。下面,我会分多种方式来保存我们的数据,避免你耍流氓。

保存到 Json
import json
class JsonPipeline(object):
    file_name = base_dir + '/doubanTop250/data.json'  # json 文件路径
    def process_item(self, item, spider):
 file = open(self.file_name, 'r', encoding='utf-8')
 load_data = json.load(file)
 load_data.append({"title": item["title"].strip()}) # 追加数据
 file = open(self.file_name, 'w', encoding='utf-8')
 json.dump(load_data, file, ensure_ascii=False) # 保存数据
 file.close()
 return item

保存到 CSV
    def appendDta2Csv(self, file_name, new_headers, new_data):
 with open(file_name,'r') as f:
     f_csv = csv.reader(f)
     try:# 如何有源文件没有 headers ,将调用传进来的 headers
  headers = next(f_csv)
     except:
  headers = new_headers
     old_data = list(f_csv)
     old_data.append(new_data) # 追加新的数据
     with open(file_name, 'w') as f2:# 保存数据
  f_csv = csv.writer(f2)
  f_csv.writerow(headers)
  f_csv.writerows(old_data)
  f2.close()
     f.close()

    def process_item(self, item, spider):
 self.appendDta2Csv(self.file_name, ["title"], [item["title"].strip()])
 return item

保存到 MongoDB
from pymongo import MongoClient
import os
base_dir = os.getcwd()
class MongoPipeline(object):
    # 实现保存到mongo数据库的类,
    collection = 'douban'  # mongo 数据库的 collection 名字

    def __init__(self, mongo_uri, db_name, db_user, db_pass):
 self.mongo_uri = mongo_uri
 self.db_name = db_name
 self.db_user = db_user
 self.db_pass = db_pass

    @classmethod
    def from_crawler(cls, crawler):
 # scrapy 为我们访问settings提供了这样的一个方法,这里,
 # 我们需要从 settings.py 文件中,取得数据库的URI和数据库名称
 return cls(
     mongo_uri=crawler.settings.get('MONGO_URI'),
     db_name=crawler.settings.get('DB_NAME'),
     db_user=crawler.settings.get('DB_USER'),
     db_pass=crawler.settings.get('DB_PASS'))

    def open_spider(self, spider):  # 爬虫启动时调用,连接到数据库
 self.client = MongoClient(self.mongo_uri)
 self.zfdb = self.client[self.db_name]
 self.zfdb.authenticate(self.db_user, self.db_pass)

    def close_spider(self, spider):  # 爬虫关闭时调用,关闭数据库连接
 self.client.close()

    def process_item(self, item, spider):
 self.zfdb[self.collection].insert({"title": item["title"].strip()})
 return item

保存到 MySQL
from sqlalchemy import create_engine, Column, Integer, String, BIGINT, ForeignKey, UniqueConstraint, Index, and_, 
    or_, inspect
from sqlalchemy.orm import sessionmaker, relationship, contains_eager
class MysqlPipeline(object):
    MYSQL_URI = 'mysql+pymysql://username:password@localhost:3306/db_name'
    # echo 为 True 将会输出 SQL 原生语句
    engine = create_engine(MYSQL_URI, echo=True)
    from sqlalchemy.ext.declarative import declarative_base
    base = declarative_base()

    # 创建单表
    class Movie(base):
 __tablename__ = 'movies'
 id = Column(BIGINT, primary_key=True, autoincrement=True)
 title = Column(String(200))
    # 初始化数据库
    def init_db(self):
 self.base.metadata.create_all(self.engine)
    # 删除数据库
    def drop_db(self):
 self.base.metadata.drop_all(self.engine)
    def open_spider(self, spider):  # 爬虫启动时调用,连接到数据库
 self.init_db()
 Session = sessionmaker(bind=self.engine)
 self.session = Session()
    def process_item(self, item, spider):
 new_movie = self.Movie(title=item["title"].strip())
 self.session.add(new_movie)
 self.session.commit()
 return item


在写好相关的 pipeline 之后,需要在 settings.py 中启用相关的 pipeline,后面的数字为调用的优先级,数字是0-1000,你可以自定义。你可以所有格式都保存,也可以注释掉其他,值保留一个。

ITEM_PIPELINES = {
    'doubanTop250.pipelines.MongoPipeline': 300,
    'doubanTop250.pipelines.MysqlPipeline': 301,
    'doubanTop250.pipelines.CsvPipeline': 302,
    'doubanTop250.pipelines.JsonPipeline': 303,
}
瞎比比

数据保存就说到这里了,后台回复【scrapy初体验】获取源码,为什么获取源码的关键词都一样呢?因为每推一篇文章,代码都会升级。那么,请期待后面的代码吧,哈哈

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/221020.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号