网页视频处理

 

背景:

       身为一个MAD爱好者会经常在B站上看MAD周刊,MAD周刊将近一周的MAD依据热度做成一个排行,我会把前20的av号标题以评论的形式放在下面。前两天觉得可以自己做个自动化脚本,只要输入MAD周刊的av号就能直接给出评论的内容,通过对视频图片进行OCR识别,获得上榜的av号,然后再得到其标题,最后以txt的形式保存。

 

Python 3.7

以下

1.通过MAD周刊的av获得其标题

通过av号获得B站视频的方法

import re

import requests

headers={

   'Content-Type':'application/x-www-form-urlencoded'

}

def getVideoNameByAv(av):

    rs = requests.get('https://m.bilibili.com/video/av{}.html'.format(av),headers=header).text

    rTitle = r'"title": "(.*?)"'

    title = re.findall(rTitle, rs)

return title

 

其中返回的rs中在下面做个json数组里面包含了视频的标题(截取了部分)

<script type="application/ld+json">

    {

        "@context": "https://zhanzhang.baidu.com/contexts/cambrian.jsonld",

        "title": "【火影忍者】血 与 泪",

        "images": “”

}

import re 使用正则表达式获取title的内容

具体可参考

https://blog.youkuaiyun.com/weixin_42785547/article/details/86604762

 

2.依据Mad周刊标题创建文件夹用于保存下载的视频

import os

if madWeeklyTitle:

    path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + '\\'

    path += 'WeeklyMadRank' + madWeeklyTitle[-6:]

    if not os.path.exists(path):

        os.mkdir(path)

# 获取该py文件的绝对路径

os.path.realpath(__file__)

# 获取上一级路径

os.path.dirname()

# 命名的字符串截取,从倒数第六位往后,即No.xxx madWeeklyTitle[-6:]

字符串的截取

https://www.cnblogs.com/xunbu7/p/8074417.html

 

3.依据av号下载flv视频

https://blog.youkuaiyun.com/Enderman_xiaohei/article/details/100598003

其中我尝试了一下mp4下载,有时候可以有时候会失败。而且即使是下载的清晰度也明显不对,有空再做仔细的分析。

 

4.将视频用Opencv处理

包括以下三个部分

按一定帧数截取画面

https://blog.youkuaiyun.com/qq_37902216/article/details/84988676

黑白化

https://blog.youkuaiyun.com/u013480370/article/details/38345453

裁剪

https://blog.youkuaiyun.com/zbj18314469395/article/details/98056164

图片裁剪的两种方式

最后以这样的形式保存

 

提取图片简书上有更详细的办法,最后我还是采用了上面的简单的形式

https://www.jianshu.com/p/e3c04d4fb5f3

 

关键代码

    timeF = 100  # 视频帧计数间隔频率

    while c < 21000:  # 循环读取视频帧

        rval, frame = vc.read()

        frame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

        # 存储为图像

        if c % timeF == 0:

            pic = pic + 1

            # 每隔 timeF 帧进行存储操作

            cv.imwrite(path + '\\' + 'pic' + str(pic) + '.jpg', frame[418:438,176:294])

        c = c + 1

        cv.waitKey(1)

将裁剪与帧保存整合了一下

 

其中遇到了一些问题

OpenCV导入的问题

Python使用opencv 在VsCode上报错的问题

解决vscode报错: Module 'cv2' has no ‘XXX’ member

是VsCode检测的问题,可以直接忽略,能够正常运行。或者添加包的时候改为

from cv2 import cv2 as cv

就OK了

 

 

还有imwrite写入却没有文件的问题

是因为cv.imwrite(path,frame)path路径不能包含中文

(我排查了一晚上最后居然是因为这个又好气又好笑)

 

5.根据识别图片返回av号(数字)

刚开始采用了tesserocr,效果不是很好后来采用了百度的ocr,准确性也不是100%,不过比tesserocr整一张图片都识别不了好一些。

tesserocr也训练了自己的样本,不过效果也不好。(其实单张图片能够识别的都还行,就是会出现一整张图片都无法识别的情况,遂放弃)

https://blog.youkuaiyun.com/u012555556/article/details/80666809

Tesseract-OCR 图片数字识别的样本训练

https://blog.youkuaiyun.com/qq_39720249/article/details/89965593

安装库 tesserocr

 

后来用了百度的API

 

https://blog.youkuaiyun.com/qq_40484582/article/details/82054009

利用百度API做图像识别(py3)

 

我用的是OCR的接口https://ai.baidu.com/docs#/OCR-API-GeneralBasic/top

 

后来出现 Max retries exceeded with url 错误

因为好像是请求连接过多的原因,因为我有210张图片,一张一个request,在循环里。

通过下面的方法关闭多余连接

https://blog.youkuaiyun.com/hyfound/article/details/82184027

 

然后将返回的‘word’下的‘value’ append到List里

返回的本来应该是av号,可是还有文字,错误av号等元素,所以还要对其处理

import difflib

    rankList = []

    a = []

    for i in madNumList[::-1]:

        if not re.match(r'^\d{7,9}$', i):

            madNumList.remove(i)

    li = list(set(madNumList))

    li.sort(key=madNumList.index)

    length = len(li)

    for i in range(0, length-1):

        j = i + 1

        if difflib.SequenceMatcher(None, li[i], li[j]).ratio() >= 0.875:

            if madNumList.count(li[i]) > madNumList.count(li[j]):

                a.append(li[j])

            else:

                a.append(li[i])

    rankList = [x for x in li if x not in a]

 

以以下返回结果为例

['70186718', '70186718', '70186713', '69614182', '69614182', '69614182', '69614182', '000秒,戴上耳', '刃/最後呼吸】']

re.match(r'^\d{7,9}$', i)将List中不是数字的,数字过长的元素排除 i表示其中的元素

^\d{7,9}$ 在7位到9位的元素,具体可见

https://blog.youkuaiyun.com/Chenftli/article/details/88414321

常用正则表达式

经过正则表达式处理后变成

['70186718', '70186718', '70186713', '69614182', '69614182', '69614182', '69614182',]

如何处理被错误识别的元素呢

我的思路是先将重复元素去除成为一个li ,然后遍历这个列表,后一个元素与前一个元素比较相似度,因为8位数,一般只会出错一个,相似度为1/8的时候我们可以认为其中是被识别错误的了,然后比较两个元素在原列表中的count,count低的存入列表a,然后将列表li中含有a列表元素的元素remove,

 

li = list(set(madNumList))

li.sort(key=madNumList.index)

https://www.cnblogs.com/tianyiliang/p/7845932.html

list去重

[x for x in li if x not in a]

http://www.imooc.com/wenda/detail/566970

从另一个列表中删除所有出现在列表中的元素

 

difflib.SequenceMatcher(None, li[i], li[j]).ratio()

https://zhangnq.com/2441.html

Python去除列表list重复或相似元素的方法

 

最后可得20个av号的List

 

6.根据av号获得title再写入txt文件

with open(txtpath, "w", encoding='utf-8') as f:

要写utf-8,不然有人在标题里加入了❤就会报下面的错误

UnicodeEncodeError: 'gbk' codec can't encode character 'xxx' in position xxxx:

https://blog.youkuaiyun.com/qq_39208536/article/details/81253531

GBK问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值