爬虫综合大作业

本次作业要求来自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/3159

爬虫综合大作业

  1. 选择一个热点或者你感兴趣的主题。
  2. 选择爬取的对象与范围。
  3. 了解爬取对象的限制与约束。
  4. 爬取相应内容。
  5. 做数据分析与文本分析。
  6. 形成一篇文章,有说明、技术要点、有数据、有数据分析图形化展示与说明、文本分析图形化展示与说明。
  7. 文章公开发布。

于2009年6月26日创建,被粉丝们亲切的称为“B站”的哔哩哔哩(bilibili),现在可以说是无人不晓。但你们是否知道哔哩哔哩这名称的来历。曾经的一部动画《某科学的超电磁炮》(疯狂安利),女主

名为御坂美琴,粉丝们中的姐姐大人,发动超能力放超电磁炮的时候,电流所发出的声音被调侃为“bilibili”,为了致敬这部动画,所以就有了现在的哔哩哔哩(B站的会员等级lv0 -> lv6也是对应动画中的等级)。所以便选了与这部动画有关的视频,爬取这个视频部分弹幕(全日站排行第1的视频,有着110万的弹幕总数)

通过检查元素-->netword,去寻找有关弹幕的链接,会发现到一个与众不同的东西,名为list.so?oid=XXX的目标。查看preview的内容,会发现这就是我们要找的弹幕资源。

 

B站视频弹幕文件都有相对应的cid

# 获取视频弹幕的cid
def get_cid(url):
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        cid = json.loads(response.content.decode())["data"]["cid"]
    return cid

将弹幕内容保存到MySQL数据库中

# 将弹幕内容保存到MySQL数据库中
def save_to_sql(cid,barrage):
    conInfo = "mysql+pymysql://root:123456@localhost:3306/bilibili?charset=utf8"
    engine = create_engine(conInfo,encoding='utf-8')
    df = pd.DataFrame(barrage)
    df.to_sql(name=str(cid),con=engine,if_exists='append',index=False)

最后生成词云

# 生成词云
def make_wordCould(barrage):
    barrage = ''.join(barrage)
    ciyun = WordCloud(background_color='white',width=1000,height=600).generate(barrage)
    plt.imshow(ciyun)
    plt.axis('off')
    plt.show()

全部代码如下:

import requests
import json
import os
from lxml import etree
import pandas as pd
from sqlalchemy import create_engine
from wordcloud import WordCloud
import matplotlib.pyplot as plt

headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
    }
# 获取视频番号
def get_url():
    av = input("请输入想要爬取弹幕的B站视频av号(例如810872):")
    url = "https://api.bilibili.com/x/web-interface/view?aid={}".format(av)
    # url = "https://api.bilibili.com/x/player/pagelist?aid={}&jsonp=jsonp".format(av)
    return url

# 获取视频弹幕的cid
def get_cid(url):
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        cid = json.loads(response.content.decode())["data"]["cid"]
    return cid

def get_title(url):
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        title = json.loads(response.content.decode())["data"]["title"]
    return title
# 解析弹幕的xml,并把爬取的弹幕保存为本地txt文件
def get_barrage(cid):
    cid_url = "https://api.bilibili.com/x/v1/dm/list.so?oid={}".format(cid)
    # cid_url = "https://comment.bilibili.com/{}.xml".format(cid)
    result = requests.get(cid_url, headers=headers)
    comment_element = etree.HTML(result.content)
    barrage_list = comment_element.xpath("//d")
    txt = str(cid)+".txt"
    if os.path.exists(txt):
         os.remove(txt)
    with open(txt, 'w', encoding='utf-8') as file:
        for d in barrage_list:
             file.write(d.xpath('./text()')[0])
             file.write("\n")
# 打开弹幕文件内容
def get_text(cid):
    txt = str(cid) + ".txt"
    with open(txt, 'r', encoding='utf-8') as file:
        fp = file.read()
    barrage = fp.split('\n')
    return barrage
# 将弹幕内容保存到MySQL数据库中
def save_to_sql(cid,barrage):
    conInfo = "mysql+pymysql://root:123456@localhost:3306/bilibili?charset=utf8"
    engine = create_engine(conInfo,encoding='utf-8')
    df = pd.DataFrame(barrage)
    df.to_sql(name=str(cid),con=engine,if_exists='append',index=False)
# 统计弹幕出现次数,并保存为本地csv文件
def barrage_count(barrage,cid):
    barrage_dict = {}
    barrage_set = set(barrage)
    for br in barrage_set:
        barrage_dict[br] = barrage.count(br)
    barrage_sort = sorted(barrage_dict.items(),key=lambda x:x[1],reverse=True)
    for i in range(20):
        print(barrage_sort[i])
    file_name = str(cid)+'.csv'
    pd.DataFrame(data=barrage_sort).to_csv(file_name,encoding='utf-8')
# 生成词云
def make_wordCould(barrage):
    barrage = ''.join(barrage)
    ciyun = WordCloud(background_color='white',width=1000,height=600).generate(barrage)
    plt.imshow(ciyun)
    plt.axis('off')
    plt.show()


if __name__ == '__main__':
    url = get_url()
    cid = get_cid(url)
    get_barrage(cid)
    barrage = get_text(cid)
    save_to_sql(cid,barrage)
    barrage_count(barrage,cid)
    make_wordCould(barrage)
View Code

 

posted @ 2019-05-09 21:56  梁林森  阅读(325)  评论(0编辑  收藏  举报