Python实战:爬取微博,获取南京地铁每日客流数据

在这篇文章中,我们将使用 Python 进行网络爬虫,爬取微博上的南京地铁每日客流数据。

一、分析网页

在“南京地铁”微博主页搜索“昨日客流”关键词,搜索到每天发布的昨日客流数据。

“南京地铁”微博主页地址https://weibo.com/u/2638276292

在浏览器开发者工具界面查看相关请求 url、payload、response 等参数,可以很清晰的分析出爬虫逻辑。

爬虫代码就不展开说了,下面直接给出完整代码。分析过程可以参考之前公众号文章,写过好几篇类似的文章。

二、爬取数据

编写 python 代码,获取到过去 1035 天含有“昨日客流”关键词的微博,并保存为一个 excel 表。

保存的 excel 表如下,created_at字段是微博发送时间,text_raw字段是微博正文。

三、解析数据

对created_at字段进行正则表达式,提取出微博发送时间、前一天日期。

from datetime import datetime, timedelta# 提取出日期字符串
text = "Mon Jan 15 09:03:10 +0800 2024"
date_split = text.split()
date_str = date_split[5] + " " + date_split[1] + " " + date_split[2] + " " + date_split[3]# 将字符串转换为日期格式
created_date = datetime.strptime(date_str, '%Y %b %d %H:%M:%S')
print(created_date)# 计算客流日期,只保留年月日
traffic_date = (created_date - timedelta(days=1)).date()
print(traffic_date)

对text_raw字段进行正则表达式,提取出每天每条地铁线路的客流数量。

import retext = "#昨日客流# 南京地铁12月31日客运量408.6,其中1号线117.7,2号线102.8,3号线93.6,4号线17.9,7号线13.6,10号线15.2,S1号线13,S3号线8.7,S6号线6.5,S7号线1.9,S8号线13.7,S9号线3.9(以上单位:万)"
# 提取日期
date_pattern = r'\d{1,2}月\d{1,2}日'
date = re.search(date_pattern, text).group()# 提取客运量
traffic_all = re.findall(r"客运量(\d+\.{0,1}\d?)", text)[0]
print(traffic_all)# 提取每条地铁线路的客运量
pattern = r"(S?\d+号线\d+\.{0,1}\d?)"
matches = re.findall(pattern, text)
print(matches)data = {}
for match in matches:line_number = re.findall(r"(S?\d+号线)", match)[0]traffic_volume = re.findall(r"号线(\d+\.{0,1}\d?)", match)[0]data["str_date"] = datedata[line_number] = traffic_volume
print(data)

image-20240131195148751

四、查看异常数据

使用布尔索引筛选出包含空值的行

# 使用布尔索引筛选出包含空值的行
print(traffic_df[traffic_df.isnull().any(axis=1)])

Pycharm 显示 12 月 21 日、6 月 4 日、6 月 5 日、4 月 27 日的行存在空值:

12 月 21 日空值如下:

6 月 4 日、6 月 5 日空值如下:


4 月 27 日空值如下:

对比原始 excel,可以发现产生空值的原因是人工发微博有细节错误,导致正则表达式没有匹配出数据。

例如“10 号线,14.5”、“4 线 14.9”、“4 线 10.2”、“1 号线,86.3”,这几个字符串由于人工输入错误,没有被正则表达式匹配出来。

五、完整代码

1、爬取数据部分的完整代码:

import requests
import pandas as pdcontent_list = []for page in range(1, 200):headers = {"Cookie": "","User-Agent": ""}data = {"page": page,"uid": "2638276292","q": "昨日客流",}url = f"https://weibo.com/ajax/statuses/searchProfile?"content_json = requests.get(url=url, headers=headers, params=data).json()print("第", page, "页,本页", len(content_json['data']['list']), "条数据", content_json['data']['list'])# df = pd.DataFrame(content_json['data'])if len(content_json['data']['list']) > 0:df = pd.json_normalize(content_json['data']['list'], errors='ignore')df = df.loc[:, ['created_at', 'text_raw']]content_list.append(df)else:break# concat合并Pandas数据
df = pd.concat(content_list)
df.to_excel(f"南京地铁客运量-昨日客流1.xlsx", index=False)
print("保存完成!")# 查看 DataFrame 的行数和列数。
rows = df.shape
print("请求得到的表格行数与列数:", rows)

2、处理数据部分的完整代码:

import re
import pandas as pd
from tqdm import tqdm
from datetime import datetime, timedeltapd.set_option('display.max_rows', 500)
pd.set_option('display.max_columns', 100)
pd.set_option('display.width', 1000)def extract_info(created_at, text_raw):# 从created_at字段,提取出日期text1 = created_atdate_split = text1.split()date_str = date_split[5] + " " + date_split[1] + " " + date_split[2] + " " + date_split[3]# 将字符串转换为日期格式created_date = datetime.strptime(date_str, '%Y %b %d %H:%M:%S')# 计算客流日期,只保留年月日traffic_date = (created_date - timedelta(days=1)).date()# 从text_raw字段,提取日期、客运量text2 = text_rawdate_pattern = r'\d{1,2}月\d{1,2}日'date = re.search(date_pattern, text2).group()# 提取客运量traffic_all = re.findall(r"客运量(\d+\.{0,1}\d?)", text2)[0]# 提取每条地铁线路的客运量pattern = r"(S?\d+号线\d+\.{0,1}\d?)"matches = re.findall(pattern, text2)# data字典用来存放提取出来的数据data = {}for match in matches:line_number = re.findall(r"(S?\d+号线)", match)[0]traffic_volume = re.findall(r"号线(\d+\.{0,1}\d?)", match)[0]data["created_date"] = created_datedata["traffic_date"] = traffic_datedata["str_date"] = datedata["traffic_all"] = float(traffic_all)data[line_number] = float(traffic_volume)# 提取出来的数据存到traffic_list列表traffic_list.append(data)if __name__ == '__main__':# traffic_list列表存放数据traffic_list = []df = pd.read_excel("./南京地铁客运量-昨日客流.xlsx")# drop_duplicates()函数删除重复行df = df.drop_duplicates()tqdm.pandas(desc='提取文本信息进度条', unit="请求")  # tqdm显示进度条df.progress_apply(lambda x: extract_info(x['created_at'], x['text_raw']), axis=1)traffic_df = pd.DataFrame(traffic_list)# 使用布尔索引筛选出包含空值的行print("包含空值的行如下:")print(traffic_df[traffic_df.isnull().any(axis=1)])# 保存为excel表格traffic_df.to_excel(f"南京地铁2023年客运量数据.xlsx", index=False)print("保存完成!")# 查看 DataFrame 的行数和列数。rows = traffic_df.shapeprint("得到的表格行数与列数:", rows)

六、数据可视化

最后,我们还可以使用数据可视化工具(如 Matplotlib、Seaborn、Pyecharts 等)将南京地铁每日客流数据可视化,以便更直观地分析数据。

例如:将每月的客运量进行统计,绘制一个按月份的折线图。

代码如下:

import pandas as pd
import matplotlib.pyplot as plt# 读取Excel文件
df = pd.read_excel('南京地铁2023年客运量数据.xlsx')# # 将traffic_date列转换为日期类型
# df['traffic_date'] = pd.to_datetime(df['traffic_date'])# 计算每月的客运量总量
monthly_traffic = df.groupby(pd.Grouper(key='traffic_date', freq='M'))['traffic_all'].sum().reset_index()# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 绘制折线图
plt.figure(figsize=(12, 6))
plt.plot(monthly_traffic['traffic_date'].dt.strftime('%Y-%m'), monthly_traffic['traffic_all'])
plt.xlabel('月份')
plt.ylabel('月客运量')
plt.title('每月客运量总计')
plt.xticks(rotation=45)
plt.grid()# 在图上标记每个月的客运量数字
for i, row in monthly_traffic.iterrows():plt.annotate(f"{row['traffic_all']:.0f}",(row['traffic_date'].strftime('%Y-%m'), row['traffic_all']),xytext=(10, 10),textcoords='offset points',ha='left',va='bottom',fontsize=12)plt.show()

生成的折线图如下:

可以看到 2023 年 1 月份和 2 月份客运量明显偏低,当时疫情对出行还是产生较大影响。受后续相关政策调整后,客运量数据从 2 月份开始才逐渐恢复正常水平。

由于数据可视化不是本篇文章重点,就不展开写了,可以移步参考之前写过的几篇数据可视化的文章。

七、总结

在这篇文章中,我们使用 Python 进行网络爬虫,爬取了微博上的南京地铁每日客流数据,并且进行了数据处理和数据可视化。

爬取数据环节较为简单,多看几篇我之前发的文章,都可以轻松写出来爬虫部分的代码。

由于微博是由地铁公司的工作人员每天人工编辑发送的,其中不免有数据格式不完全一致,这给数据处理环节增加了复杂度。

本文首发在“程序员coding”公众号,欢迎关注与我一起交流学习。

本文数据集已经上传到公众号,后台回复“南京地铁”可以自取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/658975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于视觉的移载协作机器人机床上下料末端纠偏算法

摘 要 针对复合机器人在机床上下料中的定位方法,本文主要关注识别机床卡盘和末端作业面的定位。首先分 析了复合机器人在机床上下料过程中的工作原理及其基本结构,包括 AGV (自动导引车)和协作机器人 的功能及特点。然后,详细阐述了如何使用视觉系统和纠偏算法来…

京东采销急眼,隔空喊话“针对”拼多多,焦虑之下为哪般?

农历新年将至,无论是线下各大商超还是线上电商平台,皆为年终大促而“忙的不亦乐乎”,尤其是近期发生的京东采销人员在直播间向拼多多喊话,“恳请拼多多停止屏蔽,恳请拼多多直接比价”,更是将年底这场朴实无…

flink cdc,standalone模式下,任务运行一段时间taskmanager挂掉

在使用flink cdc,配置任务运行,过了几天后,任务无故取消,超时,导致taskmanager挂掉,相关异常如下: 异常1: did not react to cancelling signal interrupting; it is stuck for 30 s…

ElasticSearch基础用法

什么是ElasticSearch? Elasticsearch是一个开源的、分布式的、实时的搜索和分析引擎。它允许用户近乎实时地存储、检索大量数据,并能够高效地对其进行全文搜索、聚合和分析。 部署ES和Kibana 通常采用docker-compose部署ES(ElasticSearch)服…

寒假思维训练day17 C. Equal Frequencies

不知不觉已经过了差不多一个月了,坚持一件事情还是有点收获的,今天更新一道1600的构造。 寒假训练计划day17 摘要: Part1 题意 Part2 题解 (有数学推导,latex形式) Part3 代码 (C版本,有详细注释) Part4 我对构造题…

基于YOLOv7算法的高精度实时安全帽和背心目标检测系统(PyTorch+Pyside6+YOLOv7)

摘要:基于YOLOv7算法的高精度实时安全帽和背心目标检测系统可用于日常生活中检测与定位安全帽和安全背心,此系统可完成对输入图片、视频、文件夹以及摄像头方式的目标检测与识别,同时本系统还支持检测结果可视化与导出。本系统采用YOLOv7目标…

【电子科技大学】计算机高级图形学总复习

第一章:绪论 图形学和图像学 走样的原因和反走样 走样指的是:用离散量表示连续量引起的失真 反走样:为了提高图形的显示质量,需要减少或消除因走样带来的阶梯形或闪烁的效果,用于减少或消除这种效果的方法称为反走样…

【51单片机Keil+Proteus8.9】门锁控制电路

门锁控制电路 二、设计思路 电路设计 1.电源部分:使用BATTERY为整个电路提供电源,可以在电路中加入一个电 源开关,以便控制电源的开启和关闭。 2.处理器部分:使用AT89C51芯片作为主处理器,通过编写程序实现门锁的 …

《Lua程序设计》-- 学习9

迭代器和泛型for 迭代器和闭包 迭代器(iterator)是一种可以让我们遍历一个集合中所有元素的代码结构。在Lua语言中,通常使用函数表示迭代器:每一次调用函数时,函数会返回集合中的“下一个”元素。 一个闭包就是一个…

SD-WAN有哪些组网方式?

随着企业网络需求的不断增长和变化,SD-WAN作为一种先进的网络架构技术,提供了多种灵活的组网方式,以适应不同企业的需求。本文将介绍SD-WAN常见的几种组网方式,帮助企业更好地理解如何利用SD-WAN构建高效的网络。 1、点对点&#…

离线使用Element UI和Vue

需要依赖如下: 1.vue.js; 2.index.js(Element UI) 3.index.css(Element UI) 4.element-icons.ttf(Element UI字体) 5.element-icons.woff(Element UI图标) 下载链接如下: 链接:https://pan.baidu.com/s/1nGOi0Vm_xExRGmVp6oVLoA 提取…

【笔记】React-Native跟Android交互--简单示例

/** * 使用命令 npx react-nativelatest init DemoRN创建项目 * * "react": "18.2.0", * "react-native": "0.73.2" * * 官网有详细教程:https://reactnative.dev/docs/native-modules-android */ 一、RN invoke androi…

【读点论文】SPTS Single-Point Text Spotting

SPTS Single-Point Text Spotting ABSTRACT 现有的场景文本识别(即,端到端文本检测和识别)方法依赖于昂贵的边界框注释(例如,文本行,词级或字符级边界框)。我们首次证明,训练场景文本识别模型可以通过对每个实例的单点进行极低成…

线性代数----------学习记录

线性代数发展历程 (1)线性方程组:例如二元一次方程组; (2)行列式:determinant,克莱默,莱布尼兹; (3)矩阵:方程个数与未知数的个数可…

黑马程序员前端web入门:新浪新闻

黑马程序员前端web入门:新浪新闻 几点学习到的: 设置li无圆点: list-style: none;设置a无下划线:text-decoration: none;a属于行内元素,高度hegiht不起作用,可以设置 display: block; 把它变成块元素。此时&#xff0c…

万户 ezOFFICE wpsservlet SQL注入漏洞复现

0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品,统一的基础管理平台,实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台,将外网信息维护、客户服务、互动交流和日…

操作系统-调度算法-1(先来先服务算法 短作业优先 高响应比优先 )

文章目录 总览先来先服务算法例题 短作业优先例题(非抢占式的短作业优先调度算法)例题(抢占式的短作业优先调度算法)注意 FCFS和SJF两种算法的思考高响应比优先例题 小结 总览 先来先服务算法 不会导致饥饿:只要该进程…

拥抱变局,坚韧向新|复旦大学-华盛顿大学EMBA项目C20毕业典礼

12月初,复旦大学-华盛顿大学EMBA项目20班的学员们前往美国,完成了项目最后一次移动课堂,并在奥林商学院举办了毕业典礼。      20班的学员们在项目20周年之际入学,也是疫情以来第一个正式恢复线下授课的班级。虽然经历了一些波…

C语言基础13

今天是学习嵌入式相关内容的第十四天,以下是今日所学内容 1.结构体: 1.结构体类型定义 2.结构体变量的定义 3.结构体元素的访问 4.结构体的存储 内存对齐 结构体整体的大小必须为最大基本类型长度的整数倍 5.结构体作为函数参数 值传递 练习:定…

【pdf密码】怎么打印加密的PDF文件?

PDF文件是可以打开查看的,但是现在不能编辑、不能打印,功能栏中的功能都是灰色的,这种设置了加密的PDF文件该如何加密? 如果PDF中的大多数功能按钮以及打印按钮都是灰色的状态,那就证明是文件的问题导致不能打印的。 …