python3网络爬虫--爬取b站用户投稿视频信息(附源码)


上次写了篇 python3网络爬虫–爬取b站视频评论用户信息(附源码) 效果良好,因此再写一篇爬取用户投稿视频的爬虫,思路简单一些。不过本次将数据存储到了MySQL数据库。
本次实现:手动输入用户id,程序根据id爬取此用户的所有投稿视频信息,最终将数据存储到MySQL数据库中,并且数据存储到以用户名为数据表名的数据表中。

一.准备工作

1.工具

(1)chrome浏览器 下载地址:https://www.google.cn/chrome/,用于分析网结构。
jsonhandle 用于分析json格式化数据,下载地址:http://jsonhandle.sinaapp.com/
我用的版本是这个
(2)python3.7 下载地址:https://www.python.org/,用于编写爬虫代码。
(3)mysql-8.0.22 下载与安装详见:

https://www.cnblogs.com/winton-nfs/p/11524007.html

用于存储数据,Navicat 15 for MySQL 下载地址:https://wws.lanzous.com/iUOl7ipybib
,数据库可视化工具,用于查看,管理mysql数据库。

二.思路

1.整体思路

在这里插入图片描述

2.爬虫思路

在这里插入图片描述

三.分析网页

从第三部分开始,就是我的主要思路了

1.分析数据加载方式

首先打开一个用户的主页(我这次要爬取回形针的视频信息/doge),切换到 投稿视频 分栏 在这里插入图片描述
发现一共有168个视频,满满的干货有木有。此时,鼠标右击/ctrl+u查看网页源代码。在这里插入图片描述
发现并没有我们需要的视频相关数据,初步断定,视频数据的加载方式为ajax异步加载,此时回到视频页,点击下一页,发现url在变化,但是源代码依然没有视频数据,右击点检查/F12 打开开发者工具,切换到network选项卡,刷新网页。在这里插入图片描述
发现就在刷新这片刻,发起了91个请求,其中左侧为请求的网址,这么多数据,哪一个才是我们需要的呢?不慌,直接ctrl+f搜索即可。在这里插入图片描述

搜索到了一个结果,右侧查看到response为json格式,查看请求头。请求地址为:

https://api.bilibili.com/x/space/arc/search?mid=258150656&ps=30&tid=0&pn=1&keyword=&order=pubdate&jsonp=jsonp

目测此链接为一个搜索接口,使用Josnhandle打开它发现存在我们需要的数据!在这里插入图片描述
由此,可判断网页数据为ajax异步加载之后渲染出来的,那我们怎么构造这个网址呢?

2.分词接口url

在之前,我们分析了网页加载方式为异步加载,得到了接口地址,发现此接口需要以下参数:在这里插入图片描述
ps:这里说一下我是怎么判断参数是否需要传递,我们拿到接口url时,以“?”分割此url,?前面的协议,路径是一定有的,?后面的部分为参数部分,他们的结构为key=value,参数和参数之间以&符号相连,而这些参数中,有的是可有可无的,所以我们可以通过适当删减url参数部分,精简url地址,详解参考

详解URL的组成

3.分析用户名(mid)

设想一下我们将数据入库时,需要选择数据表,可以简单定义为一些变量,但是为了便于区分,选择以用户名为数据表名来区分数据存储。

由于在刚才的视频接口地址不能直接拿到用户名,就退回来到用户主页,这是我们想到了网页源代码中存在用户名,那就简单了,直接请求用户主页,再提取他的名字即可。

但是,我选择了另外一种方法,就是查找用户名所在的接口,ctrl+f搜索一下在这里插入图片描述

搜索到了三个结果,经过分析发现第一个为我们所需要的,地址为:

https://api.bilibili.com/x/space/acc/info?mid=258150656&jsonp=jsonp

仅需传输一个mid(用户id)即可,而mid在主页就能拿到。既然拿到了所有参数就可以开始撰写爬虫了。

四.撰写爬虫

import requests
import json
import pymysql
import time
import re

class Bilibili_User_Videos(object):

    #初始化,要先创建一个数据库,之后的操作都在这个数据库中进行
    def __init__(self):
        user='root'
        password='root'
        self.conn=pymysql.connect('localhost',user=user,password=password,port=3306,database='BiliBili',charset="utf8")
        self.cursor=self.conn.cursor()
        self.headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'}

    #获取用户名,以这个用户名作为数据表名
    def get_tablename(self):
        base_url = f'https://api.bilibili.com/x/space/acc/info?mid={key}&jsonp=jsonp'
        r = requests.get(base_url)
        _json_data = json.loads(r.text)
        table_name = _json_data.get('data').get('name')
        return table_name

    #程序解析主程序
    def parse(self,tablename):
        sql2 = f"""CREATE TABLE IF NOT EXISTS {tablename} (
               id int(5) PRIMARY KEY ,video_title VARCHAR(100),video_avid VARCHAR(20),video_bvid VARCHAR(20),video_play_num INT(10),video_comment_num VARCHAR(10),video_danmu_num VARCHAR(10),video_created DATE,video_length VARCHAR (10),video_description VARCHAR(1000),video_link VARCHAR (50)
                ) DEFAULT CHARSET utf8 COLLATE utf8_general_ci;"""
        self.cursor.execute(sql2)
        n=1
        id_num=1
        while True:
            url = f'https://api.bilibili.com/x/space/arc/search?mid={key}&ps=30&tid=0&pn={n}&keyword=&order=pubdate&jsonp=jsonp'
            r=requests.get(url,headers=self.headers)
            _json=json.loads(r.text)
            v_list=_json.get('data').get('list').get('vlist')
            # if n==1:#在数据抽取第一次将视频数量保存下来
            #     v_count = jsonpath.jsonpath(_json, '$.data.list..count')#因为分类数量不定,所以使用jsonpath去模糊匹配
            n+=1
            if len(v_list)!=0:#程序终止标志
                for video in v_list:
                    video_title=video.get('title')#标题
                    video_aid=video.get('aid')#av号
                    video_bvid=video.get('bvid')#BV号
                    video_play_num=video.get('play')#播放数量
                    video_comment_num=video.get('comment')#当前评论数量
                    video_danmu_num=video.get('video_review')#弹幕数量
                    video_created_=video.get('created')#
                    timeArray = time.localtime(video_created_)
                    video_created = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)#时间字符串格式化
                    video_length=video.get('length')#视频长度
                    video_description=video.get('description')#视频描述
                    video_link='https://www.bilibili.com/video/'+video_bvid#链接地址:固定开头+BV号
                    sql=f'insert into {tablename} values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
                    self.cursor.execute(sql,(id_num,video_title,video_aid,video_bvid,video_play_num,video_comment_num,video_danmu_num,video_created,video_length,video_description,video_link))
                    self.conn.commit()
                    id_num+=1
                    print(video_title,video_aid,video_created,video_length,video_link)
            else:
                print(f'\033[35;46m----------------------------爬取了{id_num-1}个视频----------------------------\033[0m')
                self.cursor.close()
                self.conn.close()
                break


def main():
    bilibili_user_video_parse=Bilibili_User_Videos()
    table_name=bilibili_user_video_parse.get_tablename()
    bilibili_user_video_parse.parse(table_name)



if __name__ == '__main__':
    while True:
        key=input('请输入用户id:')
        #做一个简单的判断
        judge=re.match('\d+',key)
        if judge:
            main()
            break
        else:
            print('id输入有误!')

程序正常执行,直到结束。在这里插入图片描述

五.得到数据

使用navicate for MySQL 数据库可视化工具查看我们得到的数据。在这里插入图片描述
可以看到,一共168条数据,全部保存到了MySQL中,并且数据表名为用户名。

六.总结

  • 本次爬取了b站视频主页视频信息,使用MySQL作为数据存储数据库,在代码编写过程中,能明显发现存储到Mongodb比存储到MySQL中要编写的代码多,而且在程序执行中,后者执行效率明显慢于前者,为此我还去查找了资料,希望此篇博文能对您有帮助,思路、代码方面有什么不足欢迎各位大佬指正、批评!
  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,我可以为您介绍一下如何使用 Python 爬虫爬取房产数据并保存到本地。 首先,您需要选择一个合适的网站来进行爬取。例如,可以选择链家网、安居客等房产网站。然后,您需要分析该网站的页面结构和数据请求方式,确定需要爬取哪些数据,以及如何获取这些数据。 接着,您可以使用 Python 的 requests 库来发送 HTTP 请求,获取网页内容。然后,可以使用 BeautifulSoup 库来解析网页内容,提取需要的数据。 最后,您可以使用 Python 的 Pandas 库将数据保存到本地的 Excel 或 CSV 文件中。以下是一个示例代码: ```python import requests from bs4 import BeautifulSoup import pandas as pd # 发送 HTTP 请求获取网页内容 url = 'https://bj.lianjia.com/ershoufang/' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.content, 'html.parser') # 解析网页内容,提取需要的数据 house_list = soup.find_all('div', {'class': 'info'}) data = [] for house in house_list: name = house.find('div', {'class': 'title'}).text.strip() price = house.find('div', {'class': 'price'}).text.strip() area = house.find('div', {'class': 'houseInfo'}).text.strip() data.append([name, price, area]) # 将数据保存到本地文件 df = pd.DataFrame(data, columns=['名称', '价格', '面积']) df.to_excel('house_data.xlsx', index=False) ``` 这是一个简单的示例代码,您可以根据您需要爬取的数据和网站的不同来进行修改和优化。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值