查看原文
其他

【爬虫实战】南京地铁又上热榜——客流量分析

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:王  彤,中南财经政法大学统计与数学学院

本文编辑:石  艳

技术总编:王子一

Python云端课程来啦!

      寒雪梅中尽,春风柳上归。新的一年,正值开学之际,为了感谢大家长久以来的支持和信任,爬虫俱乐部为大家送福利啦!原价2400元的Python编程培训课程,现在仅需100元即可通过腾讯课堂参与学习。详细培训大纲及报名方式请查看推文Python云端课程福利大放送!0基础也能学~或点击文末阅读原文直接报名呦~另外,对报名有任何疑问欢迎在公众号后台和腾讯课堂留言哦!

1导读

前些时日,南京地铁登上了微博热搜👇!

究其原因,我们发现是1号线发生设备故障,耽误了很多的乘客上班。查看评论,发现有很多网友评论“又发生故障了”,看来这不是南京地铁第一次发生故障所以小编尝试分析一下南京地铁客流量,可是官网并没有公布每日客流量数据,且也没有找到南京地铁客流量数据的接口。但是小编在南京地铁官微下面发现它在第二天公布昨日的客流量数据,所以小编对其中的信息进行提取并整理分析。下面让我们正式开始吧!


2原理分析

点击南京地铁微博首页,发现只能查看前三页内容,需要登录才能查看全部内容。另外,我们通过鼠标右键查看网页源代码,发现源代码中显示的内容并不完全;我们滚动鼠标滑轮将页面往下滑动,发现会经过两次刷新加载新的内容,所以我们判断网页是Ajax动态加载的。综上,我们使用python+selenium+Chrome对网页内容进行爬取。

1、定义拉动滚动条的函数

分析原理发现,页面随着滚动条滑动会刷新两次,则每次将滚动条拉取到当前最底部,页面刷新后再次拉动滚动条,重复三次则页面到达最底部。所以,我们定义将滚动条拉取到页面最底部的函数,方便在爬取数据时直接调用。

1def scroll_to_bottom(driver):
2    for i in range(3):
3        driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
4        time.sleep(3)

2、提取数据

对每一页的响应内容进行解析并提取我们需要的内容,这里我们需要的是微博发送的时间以及包含客运量信息的文本内容,如果文本中包含“南京地铁”和“客运量”字符串,就将该文本及其发送时间提取出来,最后将数据存入metro.csv文件。

1from selenium import webdriver
2import time
3import csv
4from bs4 import BeautifulSoup
5from selenium.common.exceptions import NoSuchElementException
6
7#这里要用相匹配的chromedriver版本
8driver_path = r"C:\Program Files (x86)\Google\Chrome\Application\chromedriver_win32\chromedriver.exe"
9start_url = 'https://weibo.com/u/2638276292?is_search=0&visible=0&is_all=1&is_tag=0&profile_ftype=1&page=1#feedtop'
10browser = webdriver.Chrome(executable_path=driver_path)
11#设置隐性等待时间
12browser.implicitly_wait(10)
13browser.get(start_url)
14#预留足够长的时间进行扫码登录
15time.sleep(20)
16
17for p in range(1,692):
18    time.sleep(3)
19    #将页面滚动条滑到页面最下面
20    scroll_to_bottom(browser)
21    soup = BeautifulSoup(browser.page_source,'lxml')
22    time_list = [i.text for i in soup.select('div[class="WB_from S_txt2"]')]
23    info_list = [i.text for i in soup.select('div[class="WB_text W_f14"]')]
24    with open('metro.csv','a',encoding='utf-8',newline=''as f:
25        writer = csv.writer(f)
26        daily_list = []
27        for j in zip(time_list,info_list):
28            if '南京地铁' in j[1and '客运量' in j[1]:
29                daily_list.append(j)
30        writer.writerows(daily_list)
31    print('第%s页爬取完成'%p)
32    try:
33        browser.find_element_by_link_text("下一页").click()
34    except NoSuchElementException:
35        scroll_to_bottom(browser)



3数据清洗整理

爬取完数据之后,需要对数据进行整理和清洗,在这部分中我们只展示处理结果,如有需要代码可进行后台回复获取哦~

首先将csv文件读入DataFrame中,依照数据格式对其进行处理,结果如下:

1、时间处理

我们首先要对数据框的time列进行处理。如果发送的微博文本中有时间,则使用该时间作为定位客运量的时间;如果文本中没有时间,则时间为微博发布日期的前一天。时间处理效果如下:

2、文本处理

接下来对数据框的information列进行整理,我们将每一行的文本按一定规则进行拆分提取数字信息,然后以时间为索引写入到DataFrame中。这里需要注意的是南京地铁各线路通车时间是不同的,将数据拆分后需要将数据准确写入各线路对应的列。文本处理结果如下:

3、数据清洗

是不是以为上图内容就是最终结果啦?当然不是!接下来我们还需要做以下几步工作:

① 将空值填充为0;

② 将数据框中的值改为数值型,方便后面画图分析;

③ 删除重复值。

因为有时候官方发了两遍相同的客流量数据,另外我们使用selenium爬取数据时,因为网速问题可能中断报错,虽然我们加入了try...except机制尽量避免,但是会重复爬取一页的内容。所以最后要做好数据清洗工作,再将清洗好的数据存入Excel留档。清洗好的数据,结果如下:

以上的结果输出,就可以作为下面的数据可视化的基础数据,下面我们进入数据可视化分析 👇
4
数据可视化依据上面爬取的数据,我们通过条形图、折线图、饼图进行展示,同样只展示结果,看看可以发现什么规律。
  • 条形图


上图趋势并不够明显,我们将它绘制成各个线路客运量随时间变化的折线图 👇
  • 折线图

图中,我们可以简单发现以下三点:

① 每逢过年期间,地铁客运量相较平常有明显的下降;

② 2020年由于疫情居家隔离,当然也是过年期间,各个线路地铁客运量更是达到了历史最低。这也是可以理解的,过年期间大量上班族回家过年,疫情期间更是很少出门,所以人们出行量大大减少;

③ 虽然每年呈波动性变化,但总体趋势呈现逐年上升(2020年由于特殊原因除外)。

接下来,我们分析总客运量在短期内内随时间变化的折线图,结果如下:

图中,我们可以发现,周一到周五的客流量要比周六周日的多。这也有解释:平常乘坐地铁的大部分还是工作党,休息日地铁客流量会有一定程度的下降。

  • 饼图


最后,考虑到S7宁溧线在2018年5月26日首次开通,这也是南京地铁最新开通的地铁线路。所以我们计算2018年5月26日到分析截止日期2021年3月4日各个线路客运量占比情况,绘制了如上的饼图。我们发现,在所有地铁线路中,1号线、2号线、3号线的客运量占比是非常大的,而且从爬取的微博数据中也可以发现,1号线、2号线的开通年限也是最长的。所以,地铁公司平时一定要做好地铁检修工作。虽说本篇只是简单客观的数据分析,但安全还是要靠大家,无论工作还是游玩出行,一定要多多注意安全。希望下次热榜中有关地铁的话题都是温馨的画面。今天的介绍就是这些啦。另外,这个项目肯定会有更好的处理思路和处理方式,欢迎大家在留言区留言互动。最后别忘记,点赞、转发、关注噢~
本文的完整代码,小编在后台已献上,友友们输入“南京地铁”即可获取~

对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!

往期推文推荐

renfiles:批量重命名文件的利器

Stata中字符串的处理

物以类聚——浅述k-means聚类算法

我在哪里?调用高德API获取地址经纬度信息

超级简单的条件函数,轻松生成虚拟变量

Python云端课程福利大放送!0基础也能学~

【爬虫实战】“我们,继续新故事”——爬取LOL英雄皮肤

“人像动漫化”—Python实现抖音特效

跨框架合并数据|frlink的用法,你get到了吗

《唐探3》做错了什么?|来自150万字影评的证据

爬虫俱乐部年度总结|《请回答2020》

春节假期临近,来爬爬豆瓣看看有什么好剧

putdocx生成Word文档so easy!

模糊匹配我只用这一招!

利用tushare获取财务数据

爬虫实战|Selenium爬取微信公众号标题与链接

轻轻一点,就知有没有|rqrs命令介绍

强大的正则表达式

自动群发邮件(二)——附带附件

自动群发邮件--email和smtplib基本模块的使用

批量处理变量名和标签的小方法

计算工作日的小能手——workdays

Seminar | 企业错报与银行贷款合同

Seminar | 共同基金行业的性别歧视

Seminar | 来自女儿的塑造:高管、女性社会化与企业社会责任

小贴士:Markdown的基本语法

关于我们 


微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。



此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。

投稿邮箱:statatraining@163.com投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存