02数据存入数据库-视频网站-实践-scrapy框架-python

1 构建Item

​ 在上一篇文章视频网站视频详情页-视频网站-实践-scrapy框架 中我们已经明确了要爬取的内容,下面我们要具体实现内容的抓取。

1.1 创建Item

这里给出Item类源代码如下:

from scrapy import Item, Field


class XpcWorkItem(Item):
    # 网页id
    article_id = Field()
    # 视频id
    media_id = Field()
    # 信息url
    info_url = Field()
    # 标题
    title = Field()
    # 视频appKey
    app_key = Field()
    # 视频源地址
    video_url = Field()
    # 封面
    cover = Field()
    # 分类
    category = Field()
    # 描述
    description = Field()
    # 点赞
    likes = Field()
    # 收藏
    collections = Field()
    # 播放量
    play_counts = Field()
    # 发布时间
    publish_time = Field()
    # 发布地址
    ip_location = Field()

1.2 获取目标内容

  • 分析:
    • 页面内容:我们想要获取的内容,一部分可以在页面上直接找到,比如标题,分类,发布时间等;
    • 非页面内容:比如视频源url地址,article_id等,这些需要动态获取。
  • 寻找动态获取地址:
    • 首先打开f12切换到network标签页,刷新详情页,图示:在这里插入图片描述

    • 只有在图示请求地址响应中我们又我们想要的部分内容,那么还有没有更全的响应内容呢?

    • 详情页右键->查看网页源代码,搜索appKey相关内容,我们发现图示:在这里插入图片描述

    • 我们所需的关于改视频的内容这里都有,这部分内容包含在script标签呢,那么我们下面是直接通过抓取内容呢 还是在看看,有没有更好的方式获取

    • 通过查找,我们发现这些数据是通过这个接口获取的https://app.xinpianchang.com/article/%s:%s为之前我们获取的每个视频唯一标识-aid

1.3 解析数据接口

之前我们已经解析了详情页的地址,下面我们继续通过详情页响应来解析出数据接口地址,源码如下:

    def parse_item(self, response, aid):
        yield Request('https://app.xinpianchang.com/article/%s' % aid, callback=self.parse_data, headers=self.headers)

1.4 封装Item

数据接口解析之后,下一步继续解析数据,并封装,先查看下接口响应,如下图:在这里插入图片描述

对比发现,其中发布时间响应数据是10位秒为单位的数字,而我们一般会转换为2020-10-06 18:36:00这种各种的时间字符串传递给数据库处理。索引我们通过ItemLoader来构建Item,代码如下:

from time import time, strftime, localtime

from itemloaders.processors import TakeFirst, MapCompose
from scrapy.loader import ItemLoader


def time_sec2str(sec):
    '''
        数字时间(10位秒为单位)转换为时间字符串
    :param sec: 秒
    :return:    时间字符串
    '''
    print(sec, '='*10)
    if not sec:
        return strftime('%Y-%m-%d %H:%M:%S', time())
    return strftime('%Y-%m-%d %H:%M:%S', localtime(sec))


class XpcWorkLoader(ItemLoader):
    default_output_processor = TakeFirst()
    publish_time_out = MapCompose(time_sec2str)

  • strftime:时间转换函数,时间戳转为指定格式的时间字符串
  • TakeFirst():取列表的第一项
  • MapCompose:组合

如果对ItemLoader还有啥问题,具体可以查看官方文档或者自行搜索。

ItemLoader搞定了,下面开始封装Item,代码如下:

    def parse_data(self, response):
        # 产品对象加载器
        il = XpcWorkLoader(item=XpcWorkItem(), response=response)
        # 响应数据转换为json
        ret = json.loads(response.text)
        # print(ret['data'])
        # 设置产品对象字段
        # #id
        il.add_value('article_id', ret['data']['id'])
        # #视频id
        il.add_value('media_id', ret['data']['media_id'])
        # #信息url
        il.add_value('info_url', 'https://app.xinpianchang.com/article/%s' % ret['data']['id'])
        # #视频标题
        il.add_value('title', ret['data']['title'])
        # #视频appKey
        il.add_value('app_key', ret['data']['video']['appKey'])
        # #视频源地址
        il.add_value('video_url', ret['data']['video']['content']['progressive'][0]['url'])
        # #封面
        il.add_value('cover', ret['data']['cover'])
        # #分类
        cat0 = ret['data']['categories'][0]
        il.add_value('category', cat0['category_name'] + '-' + cat0['sub']['category_name'])
        # #描述
        il.add_value('description', ret['data']['content'])
        # #点赞
        il.add_value('likes', ret['data']['count']['count_like'])
        # #收藏
        il.add_value('collections', ret['data']['count']['count_collect'])
        # #播放量
        il.add_value('play_counts', ret['data']['count']['count_view'])
        # #发布时间
        il.add_value('publish_time', ret['data']['publish_time'])
        # #发布地址
        il.add_value('ip_location', ret['data']['ip_location'])

        return il.load_item()

2 存储

数据有了,下面我们将数据存入数据库,方便其他系统调用,这里我们选择mysql数据库。

2.1 mysql

​ 数据库建库、建表等这里不再赘述,如果有相关问题,可以下面评论留言或者自行查阅相关内容,效果图示:在这里插入图片描述

2.2 pipelines

数据库、表已经创建好了,下面我们需要吧数据存入数据库,需要通过pipeline(管道),代码如下:

import pymysql


class XpcMysqlPipeline:
    def __init__(self, host, port, db, user, password):
        self.host = host
        self.port = port
        self.db = db
        self.user = user
        self.password = password

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            host=crawler.settings.get('MYSQL_HOST', '127.0.0.1'),
            port=crawler.settings.get('MYSQL_PORT', 3306),
            db=crawler.settings.get('MYSQL_DB'),
            user=crawler.settings.get('MYSQL_USER', 'root'),
            password=crawler.settings.get('MYSQL_PASSWORD', 'root')
        )

    def open_spider(self, spider):
        self.conn = pymysql.connect(
            host=self.host,
            port=self.port,
            db=self.db,
            user=self.user,
            password=self.password
        )
        self.cur = self.conn.cursor()

    def close_spider(self, spider):
        self.cur.close()
        self.conn.close()

    def process_item(self, item, spider):
        keys = item.keys()
        values = list(item.values())
        sql = 'insert into video_show({}) values ({}) '.format(
            ','.join(keys),
            ','.join(['%s'] * len(values))
        )

        # sql = 'insert into blog(title, publish, approval, unlike, `comment`, collection) values (%s, %s, %s, %s,
        # %s, %s)'
        # sql_exe = sql % tuple(val for val in values)
        # print(sql_exe, '='*10)
        self.cur.execute(sql, values)
        self.conn.commit()
        # print(self.cur._last_executed)
        return item

  • 为了后续在添加字段时,不在改动代码,这么我们没有把实际的字段名传入,而是通过字符串模板的方式实现,具体见process_item方法

  • 我们把数据库配置信息,放置在settings.py中(具体数值改为自己的),代码如下

    # mysql数据库配置
    MYSQL_HOST = '127.0.0.1'
    MYSQL_PORT = 3306
    MYSQL_DB = 'py_scrapy_xpc'
    MYSQL_USER = 'root'
    MYSQL_PASSWORD = 'root'
    MYSQL_CHARSET = 'utf-8'
    
    
  • 构建了pipelines之后,需要在settings.py中开启(具体名称改为自己的),代码如下:

    ITEM_PIPELINES = {
       'xpc.pipelines.XpcMysqlPipeline': 300,
    }
    

3 测试

​ 其他的测试我们这里不详述了,这里只展示下数据库中内容,图示:在这里插入图片描述

4 后记

如果有问题欢迎留言和交流,下面为联系方式和仓库源代码地址。

❓QQ:806797785

⭐️源代码仓库地址:https://gitee.com/gaogzhen/python-study.git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gaog2zh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值