网络爬虫获取地铁人流量数据

任务

学院的C语言课程设计选题为地铁模拟系统,除了实现购票和充值,题目还要求实现车辆调度功能,原本没有想到好的实现形式一直搁置,验收关头发现必要性。
经学长点拨,将其所做的公交车的调度方式进行移植。只需绘制发车时间与抵达终点站时间的线性图即可体现调度功能,并加入真实数据处理更具逼真性。

已有

  • 学长传给的公交车运行数据(excel表格)##
  • 微博官方账号每日公布昨日流量

过程

分别

1. 用c语言读入数据

C语言读入数据
C语言读入数据(优化版)

  • 计划任务

2. 用爬虫爬取微博数据

在多次尝试调用API均失败后,怀一线希望在网上搜寻,一个脚本可以成功运行。
可运行脚本

可通过此文章了解爬取新浪微博网站相关知识。

基础设置

# -*- coding: utf-8 -*-
import  random
import urllib.request
import json
import re

import requests
import time


#定义要爬取的微博ID为武汉地铁运营
id= str(3186945861)#(input("请输入要抓的微博uid:"))

na='a'
#设置代理IP

iplist=['112.228.161.57:8118','125.126.164.21:34592','122.72.18.35:80','163.125.151.124:9999','114.250.25.19:80']

proxy_addr="125.126.164.21:34592"

#定义页面打开函数
def use_proxy(url,proxy_addr):
    req=urllib.request.Request(url)
    req.add_header("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0")
    proxy=urllib.request.ProxyHandler({'http':random.choice(iplist)})
    opener=urllib.request.build_opener(proxy,urllib.request.HTTPHandler)
    urllib.request.install_opener(opener)
    data=urllib.request.urlopen(req).read().decode('utf-8','ignore')
    return data
#获取微博主页的containerid,爬取微博内容时需要此id
def get_containerid():
    url='https://m.weibo.cn/api/container/getIndex?type=uid&value='+id
    data=use_proxy(url,random.choice(iplist))
    content=json.loads(data).get('data')
    for data in content.get('tabsInfo').get('tabs'):
        if(data.get('tab_type')=='weibo'):
            containerid=data.get('containerid')
    return containerid

在验证可获取微博内容后,下一步就是将自己所需的数据剔出。

观察数据

###观察每一页的卡片数目,卡片即对应单个微博

for i in range(20):
    weibo_url='https://m.weibo.cn/api/container/getIndex?type=uid&value='+id+'&containerid='+get_containerid()+'&page='+str(i)
    data=use_proxy(weibo_url,random.choice(iplist))
    content=json.loads(data).get('data')
    cards=content.get('cards')
    print(len(cards))
    

运行结果
可推知,卡片为一个页面上显示的微博条目。

数据清洗

通过网上资料可知card_type为9则代表为微博内容,否则可能为广告等等。

#打印包含客流统计微博
    for card in cards:
        card_type=card.get('card_type')
        #print(card_type)
        if(card_type==9):
                mblog=card.get('mblog')
                #print(mblog)
                #if(str(mblog).find("客流")>0)  : 
                text=mblog.get('text')
                print(text)

连接上部分运行结果
运行结果

将含有【昨日客流】标签的正文提取出来。
在这里插入图片描述

利用正则表达式的知识,将所需信息提取出来

###匹配相应信息
#示例格式:
#【昨日客流】4月27日(周六),武汉城市轨道交通线网客运量(含换乘)为332.54万乘次,其中客流前五名依次为: 2号线汉口火车站、2号线江汉路站、2号线街道口站、4号线楚河汉街站、2号线中山公园站。 
print(text)
#日期:x月x日
date=re.findall('\d+月\d+日',text)[0]
#星期:周x
day=re.findall('周\S',text)[0]
#客流量
flow=re.findall('为(.*?)万乘次',text)[0]
#排名前五
ranks=re.findall('依次为:(.*?)。',text)[0]
ranks=ranks.split('、')


print(date)
print(day)
print(flow)
print(ranks)
for rank in ranks:
    print(rank)

运行结果

数据展示

通过可视化将数据展示出来,参考文章解决横坐标过长无法显示完全问题。

绘制高峰站点图像

###绘制高峰站点图像
import matplotlib.pyplot as plt
import math
font = {'family' : 'SimHei',
    'weight' : 'bold',
    'size'  : '16'}


fig3 = plt.figure(figsize=(10,6))
#plt.subplots_adjust(hspace=0.3)
# 创建子图及间隔设置
 
ax = fig3.add_subplot(2,1,1)
plt.rc('font', **font) # pass in the font dict as kwargs
plt.rc('axes',unicode_minus=False)


plt.xticks(fontsize = 17)#对坐标的值数值,大小限制
#plt.yticks(fontsize = 37)

plt.xlabel('站点', fontproperties="SimHei")
plt.ylabel('提名次数')
#网格
plt.grid()
plt.bar(list(statisStop.keys()),list(statisStop.values()))
#plt.legend()


ax.set_xticks(range(len(list(statisStop.keys()))))

ax.set_xticklabels(list(statisStop.keys()), rotation=90)
plt.savefig('./stop.jpg')

运行结果

绘制高峰流量图

##绘制高峰流量图
import matplotlib.pyplot as plt
import math
#设置字体
font = {'family' : 'SimHei',
    'weight' : 'bold',
    'size'  : '16'}

fig3 = plt.figure(figsize=(10,6))
#plt.subplots_adjust(hspace=0.3)

# 创建子图及间隔设置
ax = fig3.add_subplot(2,1,1)
plt.rc('font', **font) # pass in the font dict as kwargs
plt.rc('axes',unicode_minus=False)

#对坐标字体大小限制
plt.xticks(fontsize = 10)
#plt.yticks(fontsize = 37)

#设置坐标标签
plt.xlabel('日期')
plt.ylabel('流量(万乘次)')

#网格
plt.grid()

#将横坐标反转,符合时间逻辑
plt.plot(list(statisFlow.keys())[::-1],list(statisFlow.values())[::-1])


#设置间距
ax.set_xticks(range(0,len(list(statisFlow.keys())),7))
ax.set_xticklabels(list(statisFlow.keys())[::-7], rotation=70)

#保存图片
plt.savefig('./flow.jpg')

运行结果

写在后面

在2020年,终于将这篇早已列为草稿的计划完成。但在今天,武汉的地铁已经停止运行3天,家中电视正在不停播报关于祸起武汉的肺炎的最新进展,或者是鼓舞民众的有力声音。
在这个大时代中,自己曾经处于事发的漩涡到底还是让人感觉魔幻,开学好像也随事态的愈发严重显得遥不可及。
希望这场风波快点平歇,一切好起来!

发布了30 篇原创文章 · 获赞 2 · 访问量 764

猜你喜欢

转载自blog.csdn.net/cascara/article/details/102938210