• 前言
  • 爬取数据用的类浏览器
  • 找到我们需要的数据
    • 使用DOM提取数据
    • 使用正则表达式解析数据
  • 2018年趵突泉会停止喷涌吗
    • URL分析
    • 网页下载
    • 数据解析
    • 爬取全部数据
    • 数据保存与检索的考量
    • 绘制水位变化曲线图
    • 数据分析

前言

一般而言,网络数据爬取是指基于http/https/ftp协议的数据下载——翻译成白话,就是从特定网页上获取我们需要的数据。想象一个浏览网页的过程,大致可以分为两个步骤:

  1. 在浏览器地址栏输入网址,打开这个网页
  2. 用眼睛找到我们需要的信息

事实上,从网上爬取数据的过程和我们浏览网页的过程是一样的,同样也包含这两个步骤,只是工具略有不同而已。

  1. 使用相当于“浏览器”的组件下载网址(URL)对应的网页(源码)
  2. 使用技术手段从下载的网页(源码)上找到我们需要的数据

爬取数据用的类浏览器

python有两个内置的模块urllib和urllib2,可以用来作为爬取数据用的“浏览器”,pycurl也是一个不错的选择,可以应对更复杂的要求。

我们知道,http协议共有8种方法,真正的浏览器至少支持两种请求网页的方法:GET和POST。相对于urllib2而言,urllib模块只接受字符串参数,不能指定请求数据的方法,更无法设置请求报头。因此,urllib2被视为爬取数据所用“浏览器”的首选。

这是urllib2模块最简单的应用:

import urllib2
response = urllib2.urlopen('http://xufive.sdysit.com/')
if response.code == 200:html = response.read() # html就是我们所请求的网页的源码print html
else:print 'Response error.'

urllib2.urlopen除了可以接受字符串参数,还可以接受urllib2.Request对象。这意味着,我们可以灵活地设置请求的报头(header)。

urllib2.urlopen的构造函数原型如下:

urllib2.urlopen(url[, data[, timeout[, cafile[, capath[, cadefault[, context]]]]])

urllib2.Request的构造函数原型如下:

urllib2.Request(url[, data][, headers][, origin_req_host][, unverifiable])

找到我们需要的数据

目标数据往往以千变万化的各种形式隐匿于我们下载到的网页源码中,这就需要我们首先分析网页源码,找出目标数据的分布规律,然后再选择相应的方式获取。

使用DOM提取数据

Beautiful Soup做为python的第三方库,可以帮助我们从网页源码中找到我们需要的数据。Beautiful Soup可以从一个HTML或者XML提取数据,它包含了简单的处理、遍历、搜索文档树、修改网页元素等功能。安装非常简单(如果没有解析器,也一并安装):

pip install beautifulsoup4
pip install lxml

下面的例子演示了如何从http://xufive.sdysit.com上找到我们需要的信息。

import urllib2
from bs4 import BeautifulSoupresponse = urllib2.urlopen('http://xufive.sdysit.com/')
if response.code == 200:html = response.read()soup = BeautifulSoup(html, 'lxml')div = soup.find('div') # 找出第一个div节点print div # 查看div标签的全部信息print div.text # 打印div标签的内容print div.attrs # 打印div标签的全部属性print div['style'] # 打印div标签的样式divs = soup.find_all('div') # 找出所有的div节点for div in divs: # 遍历所有的div节点print divfor tr in divs[1].find_all('tr'): # 遍历所有的trfor td in tr.find_all('td'):print td.text
else:print 'Response error.'

使用正则表达式解析数据

有时候,目标数据隐身于大段的文本中,无法透过html标签直接获取;或者,相同的标签数量众多,而目标数据只占其中的一小部分。此时一般要借助于正则表达式了。下面的代码可以直接把年月日提取出来(提示:处理中文时,html源码和匹配模式必须使用utf-8编码,否则运行出错):

#-*- coding: utf-8 -*-
import rehtml = u"""<tr><td>2011年10月15日</td></tr><tr><td>2011年10月15日</td></tr><tr><td>2012年5月9日</td></tr><tr><td>2015年11月23日</td></tr><tr><td>2015年7月8日</td></tr><tr><td>2016年12月5日</td></tr><tr><td>2017年3月22日</td></tr><tr><td>2017年6月17日</td></tr>
"""
pattern  = re.compile(r'<td>(\d{4})年(\d{1,2})月(\d{1,2})日</td>')
data = pattern.findall(html.encode('utf-8'))
print data

2018年趵突泉会停止喷涌吗?

济南市城乡水务局网站(http://jnwater.gov.cn)每天都会发布趵突泉和黑虎泉的地下水位,并且可以查询到更早期的水位数据。本教程的目标任务是:

  • 从这个网站上下载全部的水位数据
  • 绘制指定时间段的水位变化曲线
  • 分析济南市地下水位变化规律,对2018年泉水是否会停止喷涌做出预判

URL分析

简单操作几次,我们就会发现,自2012年5月2日开始,济南市城乡水务局网站每天都会发布趵突泉和黑虎泉的地下水位数据,全部数据采用分页方式显示,每页显示20天,页面编号从1开始,第1页的URL为:

http://www.jnwater.gov.cn/list.php?catid=101&page=1

网页下载

如果使用前面的代码下载这个网页,就会发现出错了。这多少有些令人气馁,为什么会这样呢?原来,济南市城乡水务局网站做了一点手脚,限制了非浏览器访问网站。用刚才的代码访问和用浏览器访问有什么区别吗?当然,这就是请求报头中的User-Agent(用户代理)。当浏览器访问网站时,会在请求报头中声明自己是什么类型的浏览器,运行什么样的操作系统上。我们只需要在在请求报头中增加User-Agent,就可以骗过服务器了。下面是一个抓取指定页面水位数据的函数。

import urllib2def get_data_by_page(page):url = 'http://www.jnwater.gov.cn/list.php?catid=101&page=%d'%pagereq = urllib2.Request(url, '', {'User-Agent':'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'})response = urllib2.urlopen(req)if response.code == 200:html = response.read()return htmlelse:return False

数据解析

查看下载的网页源码,不难发现,趵突泉和黑虎泉的地下水位数据在html中的是这样的:

<tr><td width="25%" align="center" bgcolor="#DAE9F8" class="s14">日期</td><td width="15%" align="center" bgcolor="#DAE9F8"><span class="s14">趵突泉水位</span></td><td width="14%" align="center" bgcolor="#DAE9F8"><span class="s14">黑虎泉水位</span></td>
</tr>
<tr><td align="center" bgcolor="#DAF8E8" class="s14">2017年10月2日</td><td align="center" bgcolor="#DAF8E8" class="s14">28.20米</td><td align="center" bgcolor="#DAF8E8" class="s14">28.15米</td>
</tr>
<tr><td align="center" bgcolor="#DAF8E8" class="s14">2017年10月1日</td><td align="center" bgcolor="#DAF8E8" class="s14">28.16米</td><td align="center" bgcolor="#DAF8E8" class="s14">28.10米</td>
</tr>

结合网页实际显示效果,很容易找到水位数据的提取条件:tr标签包含3个td标签,且td标签的背景色(bdcolor)为绿色(#DAF8E8)。继续完善我们的下载函数,使之能够解析出我们需要的数据,而不是返回一个网页源码。

def get_data_by_page(page):data = list()p_date = re.compile(r'(\d{4})\D+(\d{1,2})\D+(\d{1,2})')url = 'http://www.jnwater.gov.cn/list.php?catid=101&page=%d'%pagereq = urllib2.Request(url, '', {'User-Agent':'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'})response = urllib2.urlopen(req)if response.code == 200:html = response.read()soup = BeautifulSoup(html, 'lxml')for tr in soup.find_all('tr'):tds = tr.find_all('td')if len(tds) == 3 and 'bgcolor' in tds[0].attrs and tds[0]['bgcolor'] == '#DAF8E8':year, month, day = p_date.findall(tds[0].text.encode('utf8'))[0]baotu = float(tds[1].text[:-1])heihu = float(tds[2].text[:-1])data.append(['%s-%02d-%02d'%(year, int(month), int(day)), baotu, heihu])return data

爬取全部数据

根据网站上数据分页的数量,循环调用get_data_by_page函数,并把返回结果汇总,就得了全部水位数据。这是一个简单的工作,但实际上并容易做好,这是因为:

  • 并不是每次的网页请求都会成功
  • 数据并不总是和我们期望的一致,解析过程会出现异常
  • 日期错误、数据缺失

目前已知的错误有:

  • 2015年9月9日,错写为2014年9月9日
  • 2014年6月3日,错写为2016年6月3日
  • 2013年1月31日,错写为2012年1月31日
  • 2012年10月30日数据缺失
  • 2014年3月11日数据缺失

最好的方法是,从最近的数据日期开始,使用datetime模块的timedelta对象,逐天处理,日期错误的,改正日期,缺失数据的,用前后两天的平均值补齐。

数据保存与检索的考量

待续

绘制水位变化曲线图

待续

数据分析

待续

网络数据爬取实例教程相关推荐

  1. python网络数据爬取及分析从入门到精通pdf_Python网络数据爬取及分析从入门到精通...

    这是一套以实例为主.使用Python语言讲解网络数据爬虫及分析的实战指南.本套书通俗易懂,涵盖了Python基础知识.数据爬取.数据分析.数据预处理.数据可视化.数据存储.算法评估等多方面知识,每一部 ...

  2. Python网络数据爬取及分析-智联招聘

    python网络数据爬取及分析-智联招聘 一. 数据爬取 智联招聘是一家面向大型公司和快速发展的中小企业提供一站式专业人力资源的公司,可在智联招聘网站上根据不同城市.不同职位需求搜索得到相关招聘信息. ...

  3. python网络数据爬取及分析_《Python网络数据采集》读后总结--第3章开始爬取数据及天善用户关系分析实例...

    这次介绍一下<Python网络数据采集>这本书的第3章内容(Chpt03.开始爬数据的内容), 使用了天善用户关系分析的示例来介绍一下具体实践. 1.第3章内容简介 1-getWikiLi ...

  4. 手机app数据爬取难度等级评估

    一般来说网络数据爬取有两个来源,一个是网页,另一个是移动终端(手机app):随着移动终端的普及和推广,更多的用户甚至已经放弃了网页的访问,因此爬取移动端的数据更为合适. 但是,爬取移动端app数据具有 ...

  5. 网络爬虫分析实例:基于音悦台网站榜单的数据爬取与分析

    基于音悦台网站榜单的数据爬取与分析 本实验代码:进入 一.研究背景 在互联网发展初期,网站相对较少,信息查找比较容易.然而伴随互联网爆炸性的发展,普通网络用户想找到所需的资料简直如同大海捞针,这时为满 ...

  6. python 爬虫实例 电影-Python爬虫教程-17-ajax爬取实例(豆瓣电影)

    Python爬虫教程-17-ajax爬取实例(豆瓣电影) ajax: 简单的说,就是一段js代码,通过这段代码,可以让页面发送异步的请求,或者向服务器发送一个东西,即和服务器进行交互 对于ajax: ...

  7. 十年电影票房数据爬取与分析 | 免费数据教程

    3月8日妇女节,我很期待的超级英雄电影<惊奇队长>上映了,票房表现很快过亿,但大众口碑却让人失望. 一个有趣且常见的现象是,隔壁获奖无数,口碑爆炸的<绿皮书>,票房却远远不如& ...

  8. python如何爬虫网页数据-python网络爬虫爬取网页内容

    1.什么是网络爬虫? 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自 ...

  9. python爬虫教程(五):解析库bs4及爬取实例

    大家好,今天分享的是解析库中的bs4,本文章的目的是让你知道如何使用bs4,并且附带爬取实例. 目录 一.bs4简介 二.安装及初始印象 1.安装 2.解析器 3.初始印象 三.选择元素的方法 1.方 ...

  10. 8个零代码数据爬取工具,不会Python也能轻松爬数!(附教程)

    前天给大家整理了免费数据源网站合集,看大家的反馈很积极,有粉丝留言说,她还想要爬取一些网页的数据进行分析,不知道该如何下手 目前的用的比较多数据爬取方法是用python爬虫,这两年python很火,网 ...

最新文章

  1. 你应该知道的高性能无锁队列Disruptor
  2. rasa算法_(六)RASA NLU意图分类器
  3. 在IDEA 中用maven创建web项目
  4. (c语言)和与积的运算第一篇
  5. qpython3可视图形界面_PySide——Python图形化界面入门教程(三)
  6. 关于 C语言的 按位取反 ~
  7. 论文浅尝 | GEOM-GCN: Geometric Graph Convolutional Networks
  8. linux查看hid设备,linux hid设备读写
  9. 苹果欲把 Swift 扶上位!
  10. unix服务器上传文件,Unix lrzsz命令 上传本地文件到服务器 / 发送文件到客户端...
  11. 同步方案java_【Java基础】多线程中同步的两种解决方案
  12. 华为USG6000系列防火墙的Console密码重置过程
  13. DNN硬件加速器设计1 -- 序(MIT)
  14. win10远程控制ubuntu16.04
  15. 卡瓦莱斯的世界杯往事
  16. Unity 3D环绕Demo
  17. jar error in opening zip file
  18. WiFi共享大师后无法上网
  19. 掘金「跳转外链风险提示」实现思考
  20. 解决VMware和VMbox实体机和虚拟机无法复制粘贴的问题

热门文章

  1. D3D9学习笔记之初始化Derect3D
  2. 20000条笑话保证笑死你
  3. 路由器原理和路由协议介绍
  4. 英雄无敌6服务器在哪个文件夹,win7系统英雄无敌6无法运行的解决方法
  5. linux下看学校的IPTV
  6. 读完这篇文章,你就是下一个时间管理大师。
  7. css 文本稿纸样式,word设置稿纸样式 易雪龙玩Word:将文档文字设置为方格式稿纸样式...
  8. 东北师范大学计算机学院晓辉,计算机学院
  9. pacman入门使用指南
  10. ❤️字节跳动8年测试经验,彻夜无眠整理的40道自动化测试面试题(附精准答案),爆肝2W字❤️