【爬虫实战】南京地铁又上热榜——客流量分析
本文作者:王 彤,中南财经政法大学统计与数学学院
本文编辑:石 艳
技术总编:王子一
Python云端课程来啦!
寒雪梅中尽,春风柳上归。新的一年,正值开学之际,为了感谢大家长久以来的支持和信任,爬虫俱乐部为大家送福利啦!原价2400元的Python编程培训课程,现在仅需100元即可通过腾讯课堂参与学习。详细培训大纲及报名方式请查看推文《Python云端课程福利大放送!0基础也能学~》,或点击文末阅读原文直接报名呦~另外,对报名有任何疑问欢迎在公众号后台和腾讯课堂留言哦!1导读
前些时日,南京地铁登上了微博热搜👇!
2原理分析
点击南京地铁微博首页,发现只能查看前三页内容,需要登录才能查看全部内容。另外,我们通过鼠标右键查看网页源代码,发现源代码中显示的内容并不完全;我们滚动鼠标滑轮将页面往下滑动,发现会经过两次刷新加载新的内容,所以我们判断网页是Ajax动态加载的。综上,我们使用python+selenium+Chrome对网页内容进行爬取。
分析原理发现,页面随着滚动条滑动会刷新两次,则每次将滚动条拉取到当前最底部,页面刷新后再次拉动滚动条,重复三次则页面到达最底部。所以,我们定义将滚动条拉取到页面最底部的函数,方便在爬取数据时直接调用。
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[1] and '客运量' 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年由于特殊原因除外)。
接下来,我们分析总客运量在短期内内随时间变化的折线图,结果如下:
图中,我们可以发现,周一到周五的客流量要比周六周日的多。这也有解释:平常乘坐地铁的大部分还是工作党,休息日地铁客流量会有一定程度的下降。
饼图
本文的完整代码,小编在后台已献上,友友们输入“南京地铁”即可获取~
对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
Stata中字符串的处理
我在哪里?调用高德API获取地址经纬度信息
超级简单的条件函数,轻松生成虚拟变量
Python云端课程福利大放送!0基础也能学~
【爬虫实战】“我们,继续新故事”——爬取LOL英雄皮肤
“人像动漫化”—Python实现抖音特效
《唐探3》做错了什么?|来自150万字影评的证据
爬虫俱乐部年度总结|《请回答2020》
模糊匹配我只用这一招!
利用tushare获取财务数据
爬虫实战|Selenium爬取微信公众号标题与链接
强大的正则表达式
自动群发邮件(二)——附带附件
自动群发邮件--email和smtplib基本模块的使用
计算工作日的小能手——workdays
Seminar | 企业错报与银行贷款合同
Seminar | 来自女儿的塑造:高管、女性社会化与企业社会责任
小贴士:Markdown的基本语法
关于我们
微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。
投稿邮箱:statatraining@163.com投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。