当前位置:   article > 正文

python爬虫实战(十) 热门视频信息爬取(简易版)| 接口爬取_视频爬虫

视频爬虫

上篇爬虫博客,我们组合了scrapy和selenium对生活区的视频信息进行爬取。新手来说还是比较难理解的,有没有更简单的爬取方式呢?今天,就来继续分享一下某视频热门视频爬取另一种方式:API接口爬取。

一、API接口寻找

以某视频网站的动画区的AMD为例,打开热门视频所在页面。使用谷歌浏览器的检查功能,对页面刷新,找到视频信息所在的接口,如下图所示:
在这里插入图片描述
result中共20条视频相关信息,需要爬取的字段

字段名含义
author作者名
id视频aid编号(后续爬取需要)
duration视频时长
favorite收藏数
play播放量
pubdate发布时间
review评论数
title视频名称
二、爬取分析

主要的爬取思路:找到该接口的URL,利用requests获取html文档信息。利用json模块将其转化为字典,接着利用字典各个键获取信息即可。

需要注意一点的是,该接口的URL很长,从search?后面其实都是传入下面这个字典的参数,其中page是代表当前页,time_from和time_to是限制所视频的投稿日期范围,cate_id是各个区编码代号(动画区其他部分代码号为25,47,210)
注意:构造的时候可以不用将callback传入!)
在这里插入图片描述

全部代码

import requests
import json
import time
import pandas as pd
import os
import random
os.chdir('C:/users/dell/Desktop/')
url = '为通过审核,这部分请读者自行获取URL'
head=[
    "Mozilla/5.0 (Windows NT 6.0; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 12.14",
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.14",
    "Opera/12.80 (Windows NT 5.1; U; en) Presto/2.10.289 Version/12.02",
    "Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00",
    "Opera/9.80 (Windows NT 5.1; U; zh-sg) Presto/2.9.181 Version/12.00",
]
headers={
    'user-agent':random.choice(head),
    'refer':'为通过审核,请读者自行获取'
}
def get_inf(url,headers,num):
    df = []
    for page in range(num):
        params = {
            'main_ver': 'v3',
            'search_type': 'video',
            'view_type': 'hot_rank',
            'order': 'click',
            'copy_right': -1,
            'cate_id': 24,
            'page': page,
            'pagesize': 20,
            'jsonp': 'jsonp',
            'time_from': 20201201,
            'time_to': 20201219
        }
        try:
	        r = requests.get(url,headers=headers,params=params)
	        data = json.loads(r.text)
	        inf_list = data['result']
	        for i in range(len(inf_list)):
	            author = data['result'][i]['author']
	            duration = data['result'][i]['duration']
	            collection = data['result'][i]['favorites']
	            aid = data['result'][i]['id']
	            title = data['result'][i]['title']
	            pubdate = data['result'][i]['pubdate']
	            review = data['result'][i]['review']
	            play = data['result'][i]['play']
	            df.append([author,title,pubdate,aid,duration,play,review,collection])
	        print('第{}页爬取完毕'.format(page+1))
	        time.sleep(random.randint(1,2))
        except:
            print('未爬到数据')
    df = pd.DataFrame(df,columns=['UP主','视频标题','发布时间','aid','视频时长','播放量','评论数','收藏数'])
    df.to_csv('bilibili.csv',encoding='gb18030',index=False)
    print('共{}条热门视频信息'.format(len(df)))
if __name__=='__main__':
    start = time.time()
    num = 100
    get_inf(url,headers,num)
    end = time.time()
    print('共花费{}分钟'.format(round((end-start)/60,2)))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

由于是接口爬取,速度还是非常快的,2.76分钟爬完2000条数据
在这里插入图片描述

三、更多信息爬取

当然,从上面爬取的结果可知,原视频的点赞量、投币数以及弹幕数是没有的。因此,我们可以打开任意一个热门视频,运用同样的方法进行抓包,为加快爬取速度,在此使用协程异步爬取。

import numpy as np
import aiohttp
import asyncio
import pandas as pd
import os
import random
import time
import json
os.chdir('C:/users/dell/Desktop/')

with open('aid.txt','r') as f: #将爬取得到aid保存为aid.txt
    aid = f.readlines()
df1 = []
aid_list = np.char.strip(aid,'\n')
semaphore = asyncio.Semaphore(10) #限制并发量
head=[
    "Mozilla/5.0 (Windows NT 6.0; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 12.14",
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.14",
    "Opera/12.80 (Windows NT 5.1; U; en) Presto/2.10.289 Version/12.02",
    "Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00",
    "Opera/9.80 (Windows NT 5.1; U; zh-sg) Presto/2.9.181 Version/12.00",
]
header={
    'user-agent':random.choice(head),
    'refer':'读者自行获取'
}
async def get_page(url):
    await asyncio.sleep(2)
    async with aiohttp.ClientSession() as session:
        async with await session.get(url, headers=header) as r:
            r_text = await r.text()
            return r_text

async def parse_page(text):
        try:
            data = json.loads(text)
            name = data['data']['owner']['name']
            video_name = data['data']['title']
            release_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(data['data']['pubdate'])) #时间戳转化
            like = data['data']['stat']['like']
            coin = data['data']['stat']['coin']
            collection = data['data']['stat']['favorite']
            share = data['data']['stat']['share']
            view = data['data']['stat']['view']
            dm = data['data']['stat']['danmaku']
            df1.append([name,video_name,release_time,like,coin,collection,share,view,dm])
        except:
            print('未爬到数据')

async def get_data(url):
    async with semaphore:
        text = await get_page(url)
        await parse_page(text)
    print('下载完成:', url)

def main():
    url_list = ['为通过审核,读者自行获取该部分'+aid for aid in aid_list]
    tasks = [asyncio.ensure_future(get_data(url)) for url in url_list]
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()

if __name__=='__main__':
    start = time.time()
    main()
    df1 = pd.DataFrame(df1,columns=['UP主','视频名称','发布时间','点赞数','硬币数','收藏数','分享数','播放量','弹幕数'])
    df1.to_csv('b站.csv',encoding='gb18030',index=False)
    end = time.time()
    print('共花费{}分钟'.format(round((end-start)/60,2)))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

同样爬取速度也是非常快的(早知道有接口就不用scrapy爬了,哈哈哈~),如下图所示
在这里插入图片描述

上篇博客,scrapy+selenium大概2个半小时爬完13000条数据。而这次,粗略计算一下,在网速正常的情况下,若要爬相同条数的视频信息,大约需要65分钟,又一次加快了速度!(所以,这里还是推荐大家在爬取网站前先去找找看有没有这种接口。不过像这种没有加密参数,也没有限制爬取条数限制的接口也是可遇不可求的。)

后续有时间将补上该部分的数据分析,以上就是本次分享的全部内容~

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/1012333
推荐阅读
相关标签
  

闽ICP备14008679号