2023软工K班个人编程任务

欧旦杰 2023-09-14 22:59:42

作业链接:https://github.com/GSDJ999/102101429.git

一、PSP表格

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划4060
Estimate估计这个任务需要多少时间6080
Development开发8601060
Analysis· 需求分析 (包括学习新技术)350280
Design Spec生成设计文档50220
Design Review设计复审60140
Coding Standard代码规范 (为目前的开发制定合适的规范)4020
· Design· 具体设计4040
· Coding具体编码290500
Code Review代码复审4050
Test测试(自我测试,修改代码,提交修改)120150
Reporting报告4050
· Test Repor测试报告4050
Size Measurement· 计算工作量4040
Postmortem & Process Improvement Plan事后总结, 并提出过程改进计划4040
 合计21602420

二、任务要求的实现

1.项目设计与技术栈

(1).本次作业难度较大,python得重新温习一下。在b站学习爬虫视频的教学视频,在csdn上借鉴相关的爬虫案例。遇到难点向室友求助。

(2)本次作业最大的难点是代码的编写,花的时间也是最多的。

(3)后面的数据整理也是看了实例或者向同学借鉴的,做的也比较差。

三、代码实现

import requests
import re

header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
    }

def get_Response(html_Url):  # 对于任意一个网址url,获取其html文件
    
    response = requests.get(html_Url, headers=header)
    if response.ok:
        response.encoding = 'utf-8'
        return response
    # 如果执行到这一步,就说明请求失败,报错并退出
    print(f"请求网页失败,状态码:{response.status_code}")
    SystemExit()

def get_Target_Video(target, num): # 从B站搜索栏中找排名前num的视频,爬取他们的BV号,target为搜索内容
    matches = []
    page = 0
    #从格式为 bvid:"BV....."中提取BV号
    match_Text = r'bvid:"([^"]+)"'
    for index in range(0,num,42): # 每次爬取42个BV号
        target_Url = f"https://search.bilibili.com/all?keyword={target}&o={index}&page={page}"
        print(target_Url)
        content = requests.get(target_Url,headers= header).text
        print(content)
        print(re.findall(match_Text,content))
        matches.extend(re.findall(match_Text,content))
        page += 1
    return matches[0:num]

    

def get_Cid(BV):  # 对于一个B站视频网址,获取其cid(即存储弹幕的网站key),输入为BV号
    bili_Url = f"https://www.ibilibili.com/video/{BV}/"
    content = get_Response(bili_Url).text
    # 我们用正则从html文件中提取 "bcid":"1252950136" 中的cid号
    match_Text = r'"bcid":"(\d*)"'
    match = re.search(match_Text, content)
    if match:
        cid = match.group(1)
        return cid
    # 如果执行到这一步,说明没有匹配到cid,报错并退出
    print("解析弹幕cid失败")
    SystemExit()


def get_Danmaku(cid):  # 对于一个cid,进入弹幕网站并爬取弹幕
    # danmaku(だんまく)就是弹幕的意思
    danmaku_Url = f"https://api.bilibili.com/x/v1/dm/list.so?oid={cid}"
    content = get_Response(danmaku_Url).text
    # 这样写看上去和上一个函数没什么两样,但我觉得可读性应该会好一点
    match_Text = r'<d[^>]*>([^<]+)</d>'  # 这次的格式是<d p=......>我是弹幕</d>
    matches = re.findall(match_Text, content)
    for match in matches:
        print(match)


def main():
    target = "日本核污染水排海"
    matches = get_Target_Video(target,50)
    


if __name__ == "__main__":
    main()
    # input("Press <Enter> to close\n")
import requests
from bs4 import BeautifulSoup
import re
import math
from openpyxl import Workbook
import jieba
import matplotlib.pyplot as plt
from wordcloud import WordCloud
from PIL import Image
import numpy as np

barrages_num=20#单个视频爬取弹幕数
video_num=40#爬取视频数

# 发送GET请求,获取视频页面的HTML内容
def get_video_html(url):
    response = requests.get(url)
    return response.text

# 发送GET请求,获取B站搜索结果页面的HTML内容
def get_search_results_html():
    page,html=1,''
    url = "https://search.bilibili.com/all?keyword=日本核污染水排海&order=click"
    header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36",
        "Cookie":"buvid3=2F38CD55-CCD9-0D05-EFAC-D78F4FCEE3A133631infoc; b_nut=1691060433; i-wanna-go-back=-1; _uuid=E37F628D-CE5A-5DD1-B23C-910B92326A76633722infoc; FEED_LIVE_VERSION=V8; header_theme_version=CLOSE; SESSDATA=d324dcc4%2C1706612493%2C8ce13%2A81zqyFrgt0rrTutbzOcf6NXii0x3EXBwvDIT9w6zs4rXoM6miWp779yNngwMbCD26szHztpgAAEgA; bili_jct=348a40f9dff0f5a035a9bec3dd91083c; DedeUserID=520029018; DedeUserID__ckMd5=179dfa6087c5f3f9; rpdid=|(mmJlY|~||0J'uYmu|Y|Rm); buvid4=0A6B4ED8-EFBE-C823-919F-2D38E9352F7055238-023020811-AYMpmfEzGjyejvuh2eCCkA%3D%3D; buvid_fp_plain=undefined; nostalgia_conf=-1; b_ut=5; is-2022-channel=1; LIVE_BUVID=AUTO1116911562759162; CURRENT_QUALITY=116; hit-new-style-dyn=1; hit-dyn-v2=1; CURRENT_BLACKGAP=0; fingerprint=d1f57f19105afe876875f4d406cae4a6; CURRENT_FNVAL=4048; home_feed_column=5; browser_resolution=1699-953; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTQxODU1MTIsImlhdCI6MTY5MzkyNjMxMiwicGx0IjotMX0.gFAVbUppg5H_wIZGERddzOAdrhwXERwn1ImjtxkE2AY; bili_ticket_expires=1694185512; PVID=3; buvid_fp=d1f57f19105afe876875f4d406cae4a6; b_lsid=12A610B5C_18A68640A2F; sid=6ocelinu; bp_video_offset_520029018=837948252620849161"
    }
    for page in range(math.ceil(video_num/30)):
        cur_url=url+"&page="+str(page)
        response = requests.get(cur_url,headers=header)
        html+=response.text
    return html

# 解析HTML,提取视频链接
def get_video_links(html):
    soup = BeautifulSoup(html, "html.parser")
    bvids = re.findall(r'bvid:"([^"]+)"', html)
    video_links = []
    for vid in bvids:
        video_links.append("https://www.bilibili.com/video/"+vid)
    return video_links

def tranfrom_url(url):
    url_index = url.find('bilibili')
    new_url = url[:url_index] + 'i' + url[url_index:]
    return new_url

# 解析视频页面,提取弹幕信息
def get_barrages_list(html):
    soup = BeautifulSoup(html, "html.parser")
    barrage_info = []
    barrages_url=re.findall('https://api.bilibili.com/x/v1/dm/list.so\?oid=\d+',html)
    barrages_response=requests.get(barrages_url[0])
    barrages_response.encoding='utf-8'
    barrages_list = re.findall('<d p=".*?">(.*?)</d>', barrages_response.text)
    return barrages_list

# 统计弹幕数量,并按照数量进行排序
def count_and_sort_barrages(barrage_list):
    barrages_count = {}
    for barrage in barrage_list:
        if barrage in barrages_count:
            barrages_count[barrage] += 1
        else:
            barrages_count[barrage] = 1
    sorted_barrages = sorted(barrages_count.items(), key=lambda x: x[1], reverse=True)
    return sorted_barrages

# 输出数量排名前20的弹幕
def output_top_barrages(sorted_barrages):
    for i, (barrage, count) in enumerate(sorted_barrages[:barrages_num]):
        print(f"{i+1}. 弹幕: {barrage},数量: {count}")

def save_excel(sorted_barrages):
    wb = Workbook()
    ws = wb.active
    ws.cell(row=1, column=1).value='排名'
    ws.cell(row=1, column=2).value = '数量'
    ws.cell(row=1, column=3).value = '弹幕'
    for i, row in enumerate(sorted_barrages[:20]):
        ws.cell(row=i + 2, column=1).value = 'No.'+str(i+1)
        ws.cell(row=i + 2, column=2).value = row[1]
        ws.cell(row=i + 2, column=3).value = row[0]
    wb.save('output.xlsx')

def creat_wordcloud(sorted_barrages):
    barrages_text = list(map(lambda x: x[0], sorted_barrages))
    barrages_cut=jieba.lcut(''.join(barrages_text))
    text = ' '.join(barrages_cut)
    stop={'了','死','的','是','吧','啊'}
    background_img=np.array(Image.open('earth_mask.jpg'))
    # 生成对象
    wc = WordCloud(font_path='simsun.ttc',
                   width=800, height=600,
                   max_words=400,
                   mode="RGBA",
                   background_color='lightblue',
                   mask=background_img,
                   stopwords=stop).generate(text)
    # 显示词云图
    plt.imshow(wc, interpolation="bilinear")
    plt.axis("off")
    plt.show()

# 主函数
def main():
    print("------开始爬取,等待一段时间------")
    search_results_html = get_search_results_html()
    video_links = get_video_links(search_results_html)
    barrage_info = []
    index = 0
    for link in video_links[:video_num]:
        new_link=tranfrom_url(link)
        video_page_html = get_video_html(new_link)
        barrage_info.extend(get_barrages_list(video_page_html))
        index+=1
        print(f'已爬取{index}条视频')
    sorted_barrages = count_and_sort_barrages(barrage_info)
    output_top_barrages(sorted_barrages)
    save_excel(sorted_barrages)
    creat_wordcloud(sorted_barrages)

# 执行主函数
if __name__ == "__main__":
    main()

四.可视化页面

 

五.心得体会

最大的心得就是差距太大了,对我来说难度太大了。做的稀里糊涂,交个差也很难,需要提升的地方太多了。付出的时间也要增加。多接触一些实例,多读有用的文章。各方面的技术不达标,得多付出点时间。这次作业也是看到了代码的神奇之处,之前接触太少了,小时候也没碰过电脑,这次算是激起了我的一点兴趣。

...全文
62 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

117

社区成员

发帖
与我相关
我的任务
社区描述
2023福州大学软件工程K班
软件工程 高校 福建省·福州市
社区管理员
  • kevinkex
  • Devil angel
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧