Python制作简单的网页爬虫


Posted in Python onNovember 22, 2015

1.准备工作:

工欲善其事必先利其器,因此我们有必要在进行Coding前先配置一个适合我们自己的开发环境,我搭建的开发环境是:

操作系统:Ubuntu 14.04 LTS
Python版本:2.7.6
代码编辑器:Sublime Text 3.0

这次的网络爬虫需求背景我打算延续DotNet开源大本营在他的那篇文章中的需求,这里就不再详解。我们只抓取某一省中所有主要城市从2015-11-22到2015-10-24的白天到夜间的所有天气情况。这里以湖北省为例。
2.实战网页爬虫:
2.1.获取城市列表:
首先,我们需要获取到湖北省所有城市的网页,然后进行网页解析。网络地址为:http://www.tianqihoubao.com/weather/province.aspx?id=420000
我们查看该网页的源码可以发现所有的城市列表都是以<td style="height: 22px" align="center"><a href="城市天气链接+城市名称">,因此,我们可以封装一个函数来通过使用正则表达式获取我们想要的数据,示例代码如下所示:

def  ShowCity():

    html=requests.get("http://www.tianqihoubao.com/weather/province.aspx?id=420000")

    citys= re.findall('<td style="height: 22px" align="center"><a href="(.*?)">', html.text,re.S)

    for city in citys:

        print city

抓取的结果如下所示:
1 top/anlu.html" title="安陆历史天气查询
 2 top/badong.html" title="巴东历史天气查询
 3 top/baokang.html" title="保康历史天气查询
 4 top/caidian.html" title="蔡甸历史天气查询
 5 top/changyang.html" title="长阳历史天气查询
 6 top/chibi.html" title="赤壁历史天气查询
 7 top/chongyang.html" title="崇阳历史天气查询
 8 top/dawu.html" title="大悟历史天气查询
 9 top/daye.html" title="大冶历史天气查询
10 top/danjiangkou.html" title="丹江口历史天气查询
11 top/dangyang.html" title="当阳历史天气查询
12 top/ezhou.html" title="鄂州历史天气查询
13 top/enshi.html" title="恩施历史天气查询
14 top/fangxian.html" title="房县历史天气查询
15 top/gongan.html" title="公安历史天气查询
16 top/gucheng.html" title="谷城历史天气查询
17 top/guangshui.html" title="广水历史天气查询
18 top/hanchuan.html" title="汉川历史天气查询
19 top/hanyang.html" title="汉阳历史天气查询
20 top/hefeng.html" title="鹤峰历史天气查询
21 top/hongan.html" title="红安历史天气查询
22 top/honghu.html" title="洪湖历史天气查询
23 top/huangpi.html" title="黄陂历史天气查询
24 top/huanggang.html" title="黄冈历史天气查询
25 top/huangmei.html" title="黄梅历史天气查询
26 top/huangshi.html" title="黄石历史天气查询
27 top/jiayu.html" title="嘉鱼历史天气查询
28 top/jianli.html" title="监利历史天气查询
29 top/jianshi.html" title="建始历史天气查询
30 top/jiangxia.html" title="江夏历史天气查询
31 top/jingshan.html" title="京山历史天气查询
32 top/jingmen.html" title="荆门历史天气查询
33 top/jingzhou.html" title="荆州历史天气查询
34 top/laifeng.html" title="来凤历史天气查询
35 top/laohekou.html" title="老河口历史天气查询
36 top/lichuan.html" title="利川历史天气查询
37 top/lvtian.html" title="罗田历史天气查询
38 top/macheng.html" title="麻城历史天气查询
39 top/nanzhang.html" title="南漳历史天气查询
40 top/qichun.html" title="蕲春历史天气查询
41 top/qianjiang.html" title="潜江历史天气查询
42 top/sanxia.html" title="三峡历史天气查询
43 top/shennongjia.html" title="神农架历史天气查询
44 top/shiyan.html" title="十堰历史天气查询
45 top/shishou.html" title="石首历史天气查询
46 top/songzi.html" title="松滋历史天气查询
47 top/suizhou.html" title="随州历史天气查询
48 top/tianmen.html" title="天门历史天气查询
49 top/hbtongcheng.html" title="通城历史天气查询
50 top/tongshan.html" title="通山历史天气查询
51 top/wufeng.html" title="五峰历史天气查询
52 top/wuchang.html" title="武昌历史天气查询
53 top/wuhan.html" title="武汉历史天气查询
54 top/wuxue.html" title="武穴历史天气查询
55 top/hbxishui.html" title="浠水历史天气查询
56 top/xiantao.html" title="仙桃历史天气查询
57 top/xianfeng.html" title="咸丰历史天气查询
58 top/xianning.html" title="咸宁历史天气查询
59 top/xiangyang.html" title="襄阳历史天气查询
60 top/xiaogan.html" title="孝感历史天气查询
61 top/hbxinzhou.html" title="新洲历史天气查询
62 top/xingshan.html" title="兴山历史天气查询
63 top/xuanen.html" title="宣恩历史天气查询
64 top/hbyangxin.html" title="阳新历史天气查询
65 top/yiling.html" title="夷陵历史天气查询
66 top/yichang.html" title="宜昌历史天气查询
67 top/yicheng.html" title="宜城历史天气查询
68 top/yidu.html" title="宜都历史天气查询
69 top/yingcheng.html" title="应城历史天气查询
70 top/hbyingshan.html" title="英山历史天气查询
71 top/yuanan.html" title="远安历史天气查询
72 top/yunmeng.html" title="云梦历史天气查询
73 top/yunxi.html" title="郧西历史天气查询
74 top/hbyunxian.html" title="郧县历史天气查询
75 top/zaoyang.html" title="枣阳历史天气查询
76 top/zhijiang.html" title="枝江历史天气查询
77 top/zhongxiang.html" title="钟祥历史天气查询
78 top/zhushan.html" title="竹山历史天气查询
79 top/zhuxi.html" title="竹溪历史天气查询
80 top/zigui.html" title="秭归历史天气查询
81 [Finished in 15.4s]

2.2.获取对应城市的所有天气信息:
然后我们需要根据抓取到的城市链接去抓取对应城市的天气情况,这里我们再封装一个函数用于显示对应城市的所有天气状况:

def ShowWeather(city):
 res =str(city).split('" title="')
 print res[1],'(白天-->夜间)'
 html=requests.get("http://www.tianqihoubao.com/weather/{0}".format(res[0]))
 weather=re.search('<table width="100%" border="0" class="b" cellpadding="1" cellspacing="1">(.*?)</table>', html.text,re.S).group(1)
 res=re.findall('<tr>(.*?)</tr>', weather,re.S)
 for x in res[2:]:
  w = re.findall('>(.*?)<', x,re.S)
  for y in w[1:]:
   if len(y.strip())<=0:
    pass
    else:
     print y
  print '--'*40

这样以来,我们就可以获取到了对应城市的天气情况了!!

完整代码:

#coding:UTF-8
import re
import requests
import sys
reload(sys)
sys.setdefaultencoding('UTF-8')

def ShowWeather(city):
 res =str(city).split('" title="')
 print res[1],'(白天-->夜间)'
 html=requests.get("http://www.tianqihoubao.com/weather/{0}".format(res[0]))
 weather=re.search('<table width="100%" border="0" class="b" cellpadding="1" cellspacing="1">(.*?)</table>', html.text,re.S).group(1)
 res=re.findall('<tr>(.*?)</tr>', weather,re.S)
 for x in res[2:]:
  w = re.findall('>(.*?)<', x,re.S)
  for y in w[1:]:
   if len(y.strip())<=0:
    pass
   else:
    print y
  print '--'*40
 print '\n','*'*40

def ShowCity():
 html=requests.get("http://www.tianqihoubao.com/weather/province.aspx?id=420000")
 citys= re.findall('<td style="height: 22px" align="center"><a href="(.*?)">', html.text,re.S)
 for city in citys:
  ShowWeather(city)

def main():
 ShowCity()

if __name__=='__main__':
 main()

是的,你没有看错,短短34行代码就可以爬取湖北省所有的主要城市1个月的所有天气情况,是不是很厉害呀!!???不过不要高兴的太早,凡事有利有弊,看看它的运行结果吧:[Finished in 371.8s]

3.知识总结:

3.1.编码问题: 
#在ubuntu上,由于编码问题,我们需要在代码的开始位置添加一行注释,告诉Pyhton解释器我们指定的编码格式:

#此外,我们还需要设置默认的编码格式,否则Sublime Text会无法识别中文,报告一个错误:“UnicodeEncodeError: 'ascii' codec can't encode characters in position”

#-*-coding:utf8-*-
import sys
reload(sys)
sys.setdefaultencoding('UTF-8')

3.2.正则表达式:

导入正则表达式库:import re
匹配任意字符:.
匹配前一个字符0次或无限次:*
匹配前一个字符0次或一次:?
贪心算法:.*
非贪心算法:.*?
匹配数字:(\d+)
常用函数:

re.findall(pattern, string)
re.search(pattern, string)
re.sub(pattern, repl, string)

最后的最后,如果你尝试过运行我贴出来的完整代码,或许你会遇到和我一样的瓶颈,就是运行的速度不够快(尤其像我这种机器配置不是很好的电脑)。在我的机器上运行这段脚本总共花费了 371.8s。我运行过多次,每次都是在350+。因此,如果你的程序不在乎运行速度,那么可能Python还是挺适合的,毕竟可以通过它写更少的代码去做更多的事情!!!!

Python 相关文章推荐
在Python中操作字典之clear()方法的使用
May 21 Python
python实现上传下载文件功能
Nov 19 Python
R语言 vs Python对比:数据分析哪家强?
Nov 17 Python
Python判断一个三位数是否为水仙花数的示例
Nov 13 Python
python 求某条线上特定x值或y值的点坐标方法
Jul 09 Python
Python多叉树的构造及取出节点数据(treelib)的方法
Aug 09 Python
django项目用higcharts统计最近七天文章点击量
Aug 17 Python
Python3从零开始搭建一个语音对话机器人的实现
Aug 23 Python
python 画条形图(柱状图)实例
Apr 24 Python
keras.layer.input()用法说明
Jun 16 Python
关于python3.7安装matplotlib始终无法成功的问题的解决
Jul 28 Python
python判断变量是否为列表的方法
Sep 17 Python
Python编程中使用Pillow来处理图像的基础教程
Nov 20 #Python
在Mac OS系统上安装Python的Pillow库的教程
Nov 20 #Python
详解Python编程中time模块的使用
Nov 20 #Python
Windows上配置Emacs来开发Python及用Python扩展Emacs
Nov 20 #Python
将Emacs打造成强大的Python代码编辑工具
Nov 20 #Python
Python聚类算法之DBSACN实例分析
Nov 20 #Python
Python聚类算法之凝聚层次聚类实例分析
Nov 20 #Python
You might like
咖啡与水的关系
2021/03/03 冲泡冲煮
php将远程图片保存到本地服务器的实现代码
2015/08/03 PHP
Swoole4.4协程抢占式调度器详解
2019/05/23 PHP
js 效率组装字符串 StringBuffer
2009/12/23 Javascript
js给dropdownlist添加选项的小例子
2013/03/04 Javascript
JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
2014/08/16 Javascript
javascript实现百度地图鼠标滑动事件显示、隐藏
2015/04/02 Javascript
jquery实现可点击伸缩与展开的菜单效果代码
2015/08/31 Javascript
简单实现js悬浮导航效果
2017/02/05 Javascript
详解使用PM2管理nodejs进程
2017/10/24 NodeJs
vue移动端微信授权登录插件封装的实例
2018/08/28 Javascript
ajaxfileupload.js实现上传文件功能
2019/04/19 Javascript
layui字体图标 loading图标静止不旋转的解决方法
2019/09/23 Javascript
python创建和使用字典实例详解
2013/11/01 Python
在Python中处理日期和时间的基本知识点整理汇总
2015/05/22 Python
Python如何快速实现分布式任务
2017/07/06 Python
浅析Python3爬虫登录模拟
2018/02/07 Python
python爬虫URL重试机制的实现方法(python2.7以及python3.5)
2018/12/18 Python
Python中的异常处理try/except/finally/raise用法分析
2019/02/28 Python
Python 闭包,函数分隔作用域,nonlocal声明非局部变量操作示例
2019/10/14 Python
如何使用Python破解ZIP或RAR压缩文件密码
2020/01/09 Python
python实现logistic分类算法代码
2020/02/28 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
2020/06/28 Python
Python 解析简单的XML数据
2020/07/24 Python
一款纯css3制作的2015年元旦雪人动画特效教程
2014/12/29 HTML / CSS
皇家阿尔伯特英国官方商店:Royal Albert骨瓷
2019/03/25 全球购物
介绍一下Linux中的链接
2016/05/28 面试题
学习党课思想汇报
2013/12/29 职场文书
优秀中学生事迹材料
2014/01/31 职场文书
高三自我评价
2014/02/01 职场文书
大学新生军训感言
2014/02/25 职场文书
党支部特色活动方案
2014/08/20 职场文书
大学生读书笔记范文
2015/07/01 职场文书
公司劳动纪律管理制度
2015/08/04 职场文书
导游词之新疆-喀纳斯
2019/10/10 职场文书
mysql left join快速转inner join的过程
2021/06/30 MySQL