20224205 实验四《Python程序设计》实验报告

20224205周昭一 2024-05-28 23:59:52

20224205 2023-2024-2 《Python程序设计》实验四报告

课程:《Python程序设计》
班级: 2242
姓名: 周昭一
学号:20224205
实验教师:王志强
实验日期:2024年5月14日
必修/选修: 专选课

1.实验内容

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
课代表和各小组负责人收集作业(源代码、视频、综合实践报告)

例如:编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。

例如:利用公开数据集,开展图像分类、恶意软件检测等

例如:利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。

例如:爬取天气数据,实现自动化微信提醒

例如:利用爬虫,实现自动化下载网站视频、文件等。

例如:编写小游戏:坦克大战、贪吃蛇、扫雷等等

注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。

2. 实验过程及结果

编写爬虫,爬取微博评论,实现舆情可视化

 1)选择一个希望爬取的微博页面,打开评论区。

img

2)鼠标单击右键,在弹窗中点击“检查”,打开检查窗口,在第一横栏中点击“网络”。开始录制屏幕中显示的评论,在“网络”窗格下方的“名称”栏会显示出已录制的评论名称,点击一项名称,在“标头”(headline)栏下找到“请求URL” "user-agent" "cookie" "accept" "accept-encoding" "accept-language" "referer"等信息。
分别粘贴在代码里面,组成请求头。如图所示。

img

img

img

3)导入部分所需的Python库,包括os, requests, pandas, datetime, time, random, 这些库分别用于文件操作、网络请求、数据分析、时间处理、延时以及模拟浏览器请求头。

img

4)使用requests.get()发送访问请求,解析返回的json数据,提取评论信息,并处理异常情况。

img

5)对每个微博ID,初始化max_id为'0',循环爬取指定页数的评论数据;同时,根据当前页数和max_id构建请求URL,设置请求头,模拟浏览器访问。
注意:每次请求前后加入随机延时,避免因频繁请求被服务器封禁。

img

6)使用“def”定义辅助函数。
trans_time()函数:用于将微博返回的时间戳(GMT格式)转换为标准日期时间格式。
tran_gender()函数:根据性别标签('m'或'f')转换为中文表示。

img

7)使用正则表达式清洗评论文本,整合所有评论数据到DataFrame,然后写入CSV文件,注意处理文件是否存在的情况以决定是否写入表头,以实现数据清洗与存储。

img

8)最后的if name == 'main':块确保当主函数直接运行时,执行指定微博ID的评论爬取,输入我需要爬取的微博ID,然后调用get_comments()函数。
注意:微博ID需要在微博手机端上查看。方法:打开该微博窗口,在右上角三个点”更多选项“处点击,选择下方”复制链接“,即可复制到本条微博链接,,链接最后的一段5035843484127782就是我需要的微博ID,如我需要的微博链接为https://weibo.com/2803301701/5035843484127782%E3%80%82

img

img

9)运行该代码。运行成功,可以成功访问该URL并生成.csv文件,打开文件,包括评论内容,评论人的ID,评论时间,IP归属地等等。同时,在根目录文件夹中可以找到评论数据的生成文件,用WPS打开即为表格,实现数据可视化。

img

img

以下是代码运行视频。

以下是源代码。

import os
import requests
import pandas as pd
import datetime
from time import sleep
import random
# from fake_useragent import UserAgent
import re


def trans_time(v_str):
    """转换GMT时间为标准格式"""
    GMT_FORMAT = '%a %b %d %H:%M:%S +0800 %Y'
    timeArray = datetime.datetime.strptime(v_str, GMT_FORMAT)
    ret_time = timeArray.strftime("%Y-%m-%d %H:%M:%S")
    return ret_time


def tran_gender(gender_tag):
    """转换性别"""
    if gender_tag == 'm':
        return '男'
    elif gender_tag == 'f':
        return '女'
    else:  # -1
        return '未知'


def get_comments(v_weibo_ids, v_comment_file, v_max_page):
    """
    爬取微博评论
    :param v_weibo_id: 微博id组成的列表
    :param v_comment_file: 保存文件名
    :param v_max_page: 最大页数
    :return: None
    """
    for weibo_id in v_weibo_ids:
        # 初始化max_id
        max_id = '0'
        # 爬取前n页,可任意修改
        for page in range(1, v_max_page + 1):
            wait_seconds = random.uniform(0, 1)  # 等待时长秒
            print('开始等待{}秒'.format(wait_seconds))
            sleep(wait_seconds)  # 随机等待
            print('开始爬取第{}页'.format(page))
            if page == 1:  # 第一页,没有max_id参数
                url = 'https://m.weibo.cn/comments/hotflow?id={}&mid={}&max_id_type=0'.format(weibo_id, weibo_id)
            else:  # 非第一页,需要max_id参数
                if str(max_id) == '0':  # 如果发现max_id为0,说明没有下一页了,break结束循环
                    print('max_id is 0, break now')
                    break
                url = 'https://m.weibo.cn/comments/hotflow?id={}&mid={}&max_id_type=0&max_id={}'.format(weibo_id,
                                                                                                        weibo_id,
                                                                                                        max_id)

            headers = {
                "user-agent": 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
                "cookie": "__bid_n=1855e52f83c12780664207; FEID=v10-766d48bf476a5b99a31684e6d4b74c98b4d133a2; __xaf_fpstarttimer__=1672634141361; __xaf_thstime__=1672634141910; __xaf_fptokentimer__=1672634142056; _T_WM=91010151027; SCF=AhqqhuU0eySfXjT2vmQ5faXpqgHtzG0tpXf6Jh1xOrIiSqjsMXmKh4wsNBFg5ejqRMTI93-xSbS-Uduk_s4NRK8.; SUB=_2A25O5c7uDeRhGedI4lIU8C3PwzyIHXVqKdKmrDV6PUJbktAKLUz1kW1NVoZ-2WIGRSgsp51DeFB9dxRhRboM7px_; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9WhWcVXRXvfX3iep9.M98zpA5JpX5K-hUgL.Fo2c1K5fehe01h52dJLoIE2LxK.LBK.LB-eLxK-L1KeLBKH7wPxQdcRLxKnLB-qLBoBt; ALF=1678330814; FPTOKEN=p16283+PpnoduGibvvEpa7Jm1K1HU2NhkUXcqTuOwltTEKQJhsj3jOo/s/CWN8838ew7/ie6v2DLIYzTNLo40f3l05g4fFF+kjYdomw3o20ziaJMA4VJXMtzUBj6vAo3zxEa+LfqjEUYQuqn3G1gHwOdB2At9OvAubnkHHfZSzJJo0v+TLKcmjTLExJW/OjHZyhR9bRoWqV/1ENZHuxKvsn7tn+pgwC2n28Q/ez8zMNkj6X0huMuaBeNA8HoQ8FuWjoyrXps7wwbRbBv8z4mumRRoqiXEOSOsASflCjKw6gkfJJ5oHmoh1hx43ugVTZqxpYLivp8aCToqFu/clIex5bB2b0WQdp59i9E1KqEiwRN6jxPjhl7EKQlruQclvFYRExGOw5KMKGZy/0CNraMcw==|PfOWxrz13V2fvzp/rEoL/lSANYW4voaw2PHjpWZ/njY=|10|b67122b33a5e1ebb87032fafdc0126ba; XSRF-TOKEN=eceae9; WEIBOCN_FROM=1110006030; mweibo_short_token=87f071037d; MLOGIN=1; M_WEIBOCN_PARAMS=oid=4865363672566456&luicode=10000011&lfid=102803&uicode=20000061&fid=4865363672566456",
                "accept": "application/json, text/plain, */*",
                "accept-encoding": "gzip, deflate, br",
                "accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
                "referer": "https://m.weibo.cn/detail/{}".format(weibo_id),
                "x-requested-with": "XMLHttpRequest",
                "mweibo-pwa": '1',
            }
            r = requests.get(url, headers=headers)  # 发送请求
            print(r.status_code)  # 查看响应码
            # print(r.json())  # 查看响应内容
            try:
                max_id = r.json()['data']['max_id']  # 获取max_id给下页请求用
                datas = r.json()['data']['data']
            except Exception as e:
                print('excepted: ' + str(e))
                continue
            page_list = []  # 评论页码
            id_list = []  # 评论id
            text_list = []  # 评论内容
            time_list = []  # 评论时间
            like_count_list = []  # 评论点赞数
            source_list = []  # 评论者IP归属地
            user_name_list = []  # 评论者姓名
            user_id_list = []  # 评论者id
            user_gender_list = []  # 评论者性别
            follow_count_list = []  # 评论者关注数
            followers_count_list = []  # 评论者粉丝数
            for data in datas:
                page_list.append(page)
                id_list.append(data['id'])
                dr = re.compile(r'<[^>]+>', re.S)  # 用正则表达式清洗评论数据
                text2 = dr.sub('', data['text'])
                text_list.append(text2)  # 评论内容
                time_list.append(trans_time(v_str=data['created_at']))  # 评论时间
                like_count_list.append(data['like_count'])  # 评论点赞数
                source_list.append(data['source'])  # 评论者IP归属地
                user_name_list.append(data['user']['screen_name'])  # 评论者姓名
                user_id_list.append(data['user']['id'])  # 评论者id
                user_gender_list.append(tran_gender(data['user']['gender']))  # 评论者性别
                follow_count_list.append(data['user']['follow_count'])  # 评论者关注数
                followers_count_list.append(data['user']['followers_count'])  # 评论者粉丝数
            df = pd.DataFrame(
                {
                    'max_id': max_id,
                    '微博id': [weibo_id] * len(time_list),
                    '评论页码': page_list,
                    '评论id': id_list,
                    '评论时间': time_list,
                    '评论点赞数': like_count_list,
                    '评论者IP归属地': source_list,
                    '评论者姓名': user_name_list,
                    '评论者id': user_id_list,
                    '评论者性别': user_gender_list,
                    '评论者关注数': follow_count_list,
                    '评论者粉丝数': followers_count_list,
                    '评论内容': text_list,
                }
            )
            if os.path.exists(v_comment_file):  # 如果文件存在,不再设置表头
                header = False
            else:  # 否则,设置csv文件表头
                header = True
            # 保存csv文件
            df.to_csv(v_comment_file, mode='a+', index=False, header=header, encoding='utf_8_sig')
            print('结果保存成功:{}'.format(v_comment_file))


if __name__ == '__main__':
    weibo_id_list = ['5035843484127782', ]  # 指定爬取微博id,可填写多个id
    max_page = 1  # 爬取最大页数
    comment_file = '数据评论.csv'
    # 如果结果文件存在,先删除
    if os.path.exists(comment_file):
        os.remove(comment_file)
    # 爬取评论
    get_comments(v_weibo_ids=weibo_id_list, v_comment_file=comment_file, v_max_page=max_page)


3.实验过程中遇到的问题及解决过程

  • 问题1:一开始import requests 的代码运行时,总是报错显示No module named 'requests'。
  • 问题1解决方案:经过上网查询,报错是因为我没有导入requests库。解决方法为,在Python运行终端(Terminal)发送指令pip install requests,使其安装requests库。

img

img

img

  • 问题2:一开始import pandas as pd 的代码运行时,总是报错显示No module named 'pandas'。
  • 问题2解决方案:经过上网查询,报错是因为我没有导入pandas库。解决方法为,在Python运行终端(Terminal)发送指令pip install pandas,使其安装pandas库。

img

img

  • 问题3:无法找到微博ID的查询方式。
  • 问题3解决方案:经过向同学寻求帮助后,我得知微博ID需要在微博手机端上查看。方法:打开该微博窗口,在右上角三个点”更多选项“处点击,选择下方”复制链接“,即可复制到本条微博链接,如我需要的微博链接为https://weibo.com/2803301701/5035843484127782%EF%BC%8C
    链接最后的一段5035843484127782就是我需要的微博ID。

img

4.实验四感想

    在编写爬虫程序的过程中,由于一开始没有太跟上老师的上课节奏,导致我后续自己实践的时候难度非常大。我自行在B站上查找了多个教学视频,结合CSDN上的一些经验分享,进行实际操作,还是阻碍重重,遇到了诸多问题,这让我一开始有点灰心。但是在找对思路后,加上同学的帮助,我获益良多,最后编写的代码运行成功。当表格文件以不到两秒的时间在我的文件夹里生成出来的时候,我激动地点开表格,看到评论内容,评论人的ID,评论时间,IP归属地等信息明明白白地在我眼前如群蚁排衙,我突然觉得信息空间所能施展拳脚的空间着实广阔,这也坚定了吾将上下而求索的决心。

5.课程总结与感想

    学习一项全新的技能,就像是在一个陌生的世界里探索的过程。我是第一次接触Python的小白,对这个陌生的世界充满了好奇与想象。事实上,在本次Python选修课中,不论是制作简易计算器,还是学习编写Socket,抑或是爬虫的应用,对于第一次接触这个领域的我来说都需要一次又一次的尝试,需要不断地试错,修正,再试错,再修正。
    在制作简易计算器的过程中,我感受到原来使用计算机语言编写代码并进行应用就像是我坐在电脑前,与电脑对话。我想通过python写出什么样的代码,实现什么样的功能,都必须用计算机能听懂的语句来输入。这帮助我更深入地去理解计算机在进行运算时的底层逻辑,原来我们日常生活中使用的非常简单的计算器操作在计算机语言中也并非如此容易。同时,在查阅资料的过程中,我还发现了制作更精良、外形更美观的使用Python编写计算器程序的教程,日后我也打算尝试深入学习,让这个简易的计算器骨骼变得有血有肉、栩栩如生。
    在编写Socket的过程中,我体验到了用代码转变为讯息传递工具的奇妙,也了解到原来通信是需要服务器端和客户端两方之间传递的。那么我不禁思考,我们平常使用的微信、QQ等实时通讯工具是不是也需要两个客户分别把自己索要传达的信息上传到服务器端,然后才能从服务器端发出呢?诸如此类的联想帮助我打开了信息世界的窗口。
    在编写爬虫程序的过程中,由于一开始没有太跟上老师的上课节奏,导致我后续自己实践的时候难度非常大。我自行在B站上查找了多个教学视频,结合CSDN上的一些经验分享,进行实际操作,还是阻碍重重,遇到了诸多问题,这让我一开始有点灰心。但是在找对思路后,加上同学的帮助,我获益良多,最后编写的代码运行成功。
    最后实验成功时的喜悦远远超越了过程中举步维艰的困难,这门课程让我深入了解了 Python 简洁而强大的语法。从基础的数据类型到复杂的控制结构,每一个知识点都构建起了我编程能力的基石。通过实际的代码编写和项目实践,我逐渐掌握了如何运用 Python 解决各种问题。课程中的实践项目让我将所学知识应用到实际场景中,锻炼了我的问题解决能力和逻辑思维。
    这门 Python 课程在帮助我掌握了一门实用的编程语言的同时,更培养了我的编程思维和解决问题的能力。我相信这些技能将在未来的学习和工作中发挥重要作用,我也期待着能运用 Python 创造更多有价值的成果。人生苦短,我爱Python
...全文
339 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
内容概要:本文研究基于粒子群算法(PSO)优化模糊C均值聚类(FCM)的居民用电行为分析方法,提出一种改进的FCM聚类算法,通过引入粒子群优化机制,有效提升聚类性能与收敛效率,克服传统FCM算法易陷入局部最优、对初始聚类中心敏感等缺陷。研究基于Matlab平台实现算法代码,对居民用电负荷数据进行聚类分析,识别不同用户的典型用电模式与行为特征,进而支持电力系统的需求侧精细化管理、用户分群运营、个性化用电服务推荐以及中长期负荷预测。该方法在智能电网与大数据背景下展现出良好的应用前景,特别适用于大规模居民用电数据的行为挖掘与模式识别任务。; 适合人群:具备一定电力系统基础知识、数据挖掘或智能优化算法背景的科研人员及工程技术人员,尤其适合从事智能电网、负荷特性分析、需求响应、用户行为研究等方向的硕士、博士研究生及高校教师。; 使用场景及目标:①实现居民用户用电行为的有效分类与典型负荷曲线提取;②优化电力客户细分策略,支撑差异化电价、需求响应激励政策的设计与实施;③为负荷预测、电网规划、配电台区管理提供数据驱动的决策依据;④作为高水平学术论文(如EI、SCI期刊)的研究基础,用于算法复现、性能对比与创新改进。; 阅读建议:建议读者结合提供的Matlab代码深入理解PSO-FCM算法的具体实现流程,重点关注粒子编码方式、适应度函数构建、聚类有效性评价指标(如轮廓系数、误差平方和)的应用,鼓励在真实用电数据集上进行实验验证,并尝试引入其他优化策略或评估维度以进一步提升模型鲁棒性与实用性。
【重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!
代码转载自:https://pan.quark.cn/s/a1913ccaa47a 在信息技术领域中,图像处理占据着核心地位,特别是在嵌入式系统以及移动设备上,由于受到资源条件的制约,常常需要将高分辨率的图像格式转化为低分辨率的格式,以此来提升显示效能和存储容量。"bmp格式转为rgb565格式图片转换工具"正是为了应对这种需求而研发的。BMP(Bitmap)是一种广泛应用的位图格式,它完整地记录了图像的每一个像素点信息,涵盖了色彩深度、透明度等参数。然而,这种格式在内存消耗和处理速率方面并不具备优势,尤其是在需要高速渲染的情境下。RGB565是一种16位的色彩编码格式,普遍应用于嵌入式系统,例如由微控制器控制的LCD显示屏。它通过分配5位红色、6位绿色以及5位蓝色分量来表现色彩,总共能够呈现2^16 = 65536种色彩,尽管其色彩数量(约1670万种)少于BMP的24位色彩,但足以满足绝大多数显示场景,并且显著降低了数据存储和传输的负担。这种转换工具的运作机制在于读取BMP文件中的每一个像素点,然后依照RGB565的编码规范重新组织色彩信息。在BMP文件中,像素数据一般以行为单位进行存储,遵循从左到右、自下而上的顺序。而在RGB565格式中,每个像素点由两个字节构成,其中红色和蓝色各占5位,绿色占据6位,这样的布局旨在提升内存中的对齐效率。转换流程通常包括以下几个环节:1. 分析BMP文件头部:BMP文件头部包含了图像的宽度、高度、色彩深度等关键数据,这是进行转换的依据。2. 获取像素数据:按照BMP文件的结构读取每一行的像素点信息。3. 色彩转换:将每个24位RGB色彩点转换为16位RGB565格式。4. 输出新格式:将转换后的RGB565数据写入新的...
内容概要:本文系统研究了基于合作博弈理论的综合能源系统利益分配优化调度方法,并配套提供了完整的Matlab代码实现。针对多个能源主体协同运行场景下的利益分配难题,文章构建了严谨的合作博弈模型,结合优化调度算法,在实现系统整体经济效益最大化的同时,确保各参与方之间的利益分配公平合理。研究内容涵盖模型的数学建模、理论推导、求解流程设计及仿真验证全过程,重点突出了Shapley值等经典博弈分配方法在能源系统中的应用,具有较强的理论深度与工程实践价值,适用于致力于高水平学术研究(如EI/SCI论文撰写)的科研人员。; 适合人群:具备电力系统、优化理论及博弈论基础知识,从事综合能源系统调度、分布式能源协同管理、能源互联网经济性分析等方向研究的硕士、博士研究生及高校科研人员。; 使用场景及目标:①用于多主体综合能源系统中利益分配机制的设计与仿真分析;②支撑高质量学术论文的撰写、复现与创新;③为实际能源项目中的协调调度决策与经济性评估提供理论依据与技术工具支持。; 阅读建议:建议读者结合Matlab代码逐模块研读,深入理解合作博弈模型与优化调度算法的耦合逻辑,重点关注Shapley值等分配机制的计算实现,并可通过调整参数或拓展模型结构进行二次开发与对比实验

93

社区成员

发帖
与我相关
我的任务
社区描述
Python程序设计作业
软件构建 高校 北京·丰台区
社区管理员
  • blackwall0321
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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