[实用]手把手教你用python抓网页数据

前言: 数据科学越来越火了,网页是数据很大的一个来源。最近很多人问怎么抓网页数据,据我所知,常见的编程语言(C++,java,python)都可以实现抓网页数据,甚至很多统计\计算的语言(R,Matlab)都有可以实现和网站交互的包。本人试过用java,python,R抓网页,感觉语法各有差异,逻辑上是一样的。我准备用python来大概讲讲抓网页是什么概念,具体的内容要自己看手册或者google别人的博客,这里算是抛砖引玉了。水平有限,出现错误或者有更好的办法,欢迎讨论。 步骤一:熟悉Python的基本语法。 已经熟悉Python的直接跳到步骤二。 Python是门比较容易入门的编程语言,如何上手视编程基础而定。 (1) 如果有一定编程的基础,建议看google's python class,链接https://developers.google.com/edu/python/?hl=zh-CN&csw=1 这个是一个为期两天的短期培训课程(当然,是两个全天),大概是七个视频,每个视频之后给编程作业,每个作业一个小时之内可以完成。这是我学习python的第二门课(第一门是codecademy的python,很早之前看的,很多内容都记不得了),当时每天看视频+编程作业一个多小时,六天弄完,效果还不错,用python写基本的程序没有问题。 (2) 如果是没有任何编程基础,建议看coursera上Rice University开的An Introduction to Interactive Programming in Python。这门课我没有跟过,但是看coursetalk的评论反映非常好,地里也有同学评论(点这里),课程链接:https://www.coursera.org/course/interactivepython。Udacity上的CS101也是不错的选择,地里有相关的讨论帖(点这里),而且这门课就叫做build a search engine,会专门讲一些和网络相关的module。其他学习资源还有code school和codecademy,这些资源也是挺不错的,但是编程量太少,初学者还是系统的跟课、多练练手来打好基础吧。 当然,每个人的偏好不同,我推荐的不一定适合你。可以先看看这个帖子【长期加分贴】介绍你上过的公开课里面其他人是怎么说的,或者上coursetalk.org看看课程评论,再决定吧。 步骤二:学会如何与网站建立链接,得到网页数据。. visit 1point3acres.comfor more. 写脚本与网站进行交互,要熟悉python和网页相关的几个module(urllib,urllib2,httplib)中的一个,知道一个即可,其他的都类似的。这三个是python提供的和网页交互的基本module,还有其他的一些,比如:mechanize和scrappy,我没有用过,可能有更好的性能,欢迎了解的来补充。基本的网页抓取,前面的三个module足矣。 下面的代码演示如何用urllib2与google scholar进行交互,获得网页信息。

1.# 导入模块 urllib2

2.import urllib2

3.. 鐣欏鐢宠璁哄潧-涓€浜╀笁鍒嗗湴

4.# 随便查询一篇文章,比如On random graph。对每一个查询google . visit1point3acres.com for more.

5.# scholar都有一个url,这个url形成的规则是要自己分析的。. 涓€浜�-涓夊垎-鍦帮紝鐙鍙戝竷

6.query = 'On+random+graph'

7.url ='http://scholar.google.com/scholar?hl=en&q=' + query +'&btnG=&as_sdt=1%2C5&as_sdtp='

8.# 设置头文件。抓取有些的网页不需要专门设置头文件,但是这里如果不设置的话,

9.# google会认为是机器人不允许访问。另外访问有些网站还有设置Cookie,这个会相对复杂一些,

10. # 这里暂时不提。关于怎么知道头文件该怎么写,一些插件可以看到你用的浏览器和网站交互的

11. # 头文件(这种工具很多浏览器是自带的),我用的是firefox的firebug插件。

12. header = {'Host': 'scholar.google.com',

13. 'User-Agent': 'Mozilla/5.0 (Windows NT6.1; rv:26.0) Gecko/20100101 Firefox/26.0',

14. 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',

15. 'Accept-Encoding': 'gzip, deflate',

16. 'Connection': 'keep-alive'}

17. # 建立连接请求,这时google的服务器返回页面信息给con这个变量,con是一个对象. 1point3acres.com/bbs

18. req = urllib2.Request(url, headers =header)

19. con = urllib2.urlopen( req )

20. # 对con这个对象调用read()方法,返回的是html页面,也就是有html标签的纯文本

21. doc = con.read(). 鐣欏鐢宠璁哄潧-涓€浜╀笁鍒嗗湴

22. # 关闭连接。就像读完文件要关闭文件一样,如果不关闭有时可以、但有时会有问题,

23. # 所以作为一个守法的好公民,还是关闭连接好了。

24. con.close()

复制代码

以上的代码就把在google scholar上查询On Random Graph的结果返回到doc这个变量中了,这个和你打开google scholar搜索On Random Graph,然后将网页右键保存的效果是一样的。 步骤三、解析网页. 鐣欏鐢宠璁哄潧-涓€浜╀笁鍒嗗湴 上面的步骤得到了网页的信息,但是包括了html标签,你要把这些标签去掉,然后从html文本中整理出有用的信息, 你需要解析这个网页。 解析网页的方法:. 鐣欏鐢宠璁哄潧-涓€浜╀笁鍒嗗湴 (1) 正则表达式。正则表达式很有用,熟悉它节省很多的时间,有时候清洗数据不用写脚本或者在数据库上查询,直接在notepad++上用正则表达式组合使用就行了。如何学习正则表达式建议看:正则表达式30分钟入门教程,链接:http://deerchao.net/tutorials/regex/regex.htm (2) BeautifulSoup模块。BeautifulSoup是一个很强大的模块,能把html文件解析成一个对象,这个对象是一棵树。我们都知道html文件是树状的,比如 body -> table ->tbody -> tr,对于tbody这个节点,有很多个tr的子节点。BeautifulSoup可以很方便的取到特定的节点,对单个节点也可以取它的sibling node。网上有很多相关的说明,这里不细说,只演示简单的代码: (3) 上面两种方法结合使用。

1.# 导入BeautifulSoup模块和re模块,re是python中正则表达式的模块

2.import BeautifulSoup

3.import re. from: 1point3acres.com/bbs

4.# 生成一个soup对象,doc就是步骤二中提到的-google 1point3acres

5.soup = BeautifulSoup.BeautifulSoup(doc)

6.# 抓取论文标题,作者,简短描述,引用次数,版本数,引用它的文章列表的超链接

7.# 这里还用了一些正则表达式,不熟悉的先无知它好了。至于'class' : 'gs_rt'中

8.# 'gs_rt'是怎么来的,这个是分析html文件肉眼看出来的。上面提到的firebug插件

9.# 让这个变的很简单,只要一点网页,就可以知道对应的html 标签的位置和属性,

10. # 相当好用。

11. paper_name = soup.html.body.find('h3',{'class' : 'gs_rt'}).text

12. paper_name = re.sub(r'\[.*\]', '',paper_name) # eliminate '[]' tags like '[PDF]'.1point3acres缃�

13. paper_author =soup.html.body.find('div', {'class' : 'gs_a'}).text

14. paper_desc = soup.html.body.find('div',{'class' : 'gs_rs'}).text

15. temp_str = soup.html.body.find('div',{'class' : 'gs_fl'}).text. more info on 1point3acres.com

16. temp_re =re.match(r'[A-Za-z\s]+(\d*)[A-Za-z\s]+(\d*)', temp_str)

17. citeTimes = temp_re.group(1)

18. versionNum = temp_re.group(2)

19. if citeTimes == '':

20. citeTimes = '0'. more info on 1point3acres.com

21. if versionNum == '':

22. versionNum = '0'. more info on 1point3acres.com

23. citedPaper_href =soup.html.body.find('div', {'class' : 'gs_fl'}).a.attrs[0][1]

复制代码

.from: 1point3acres.com/bbs 这些都是我在一个分析citation network的项目的代码。顺便一提,我从google scholar上抓取paper的信息以及引用列表的信息,访问了大概1900次左右的时候给google block了,导致这个片区的ip一时无法登陆google scholar。 步骤四:存取数据. 1point3acres.com/bbs 好不容易抓了数据,现在只是存储在内存中,必须保存起来才能利用。 (1) 最简单的方法之把数据写进txt文件中,Python中可以用如下代码实现: .涓€浜�-涓夊垎-鍦帮紝鐙鍙戝竷

1.# 打开文件webdata.txt,生成对象file,这个文件可以是不存在的,参数a表示往里面添加。

2.# 还有别的参数,比如'r'只能读但不能写入,'w'可以写入但是会删除原来的记录等等

3.file = open('webdata.txt','a')

4.line = paper_name + '#' + paper_author +'#' + paper_desc + '#' + citeTimes + '\n'. 涓€浜�-涓夊垎-鍦帮紝鐙鍙戝竷

5.# 对象file的write方法将字符串line写入file中

6.file = file.write(line)

7.# 再一次的,做个随手关闭文件的好青年

8.file.close()

复制代码

这样,就把从网页上抓到并且解析了的数据存储到本地了,是不是很简单? (2) 当然,你也可以不写入txt文件中,而是直接连接数据库,python中的MySQLdb模块可以实现和MySQL数据库的交互,把数据直接倒到数据库里面,与MySQL数据库建立链接的逻辑和与网站服务器建立链接的逻辑差不多。如果之前有学习过数据库,学习用MySQLdb模块实现和数据库的交互是很简单的;如果没有,则要借助在coursera\stanford openEdX平台上都有开设的Introduction to Database来系统学习,w3school用来参考或者当成手册。. 1point3acres.com/bbs Python能够链接数据库的前提是数据库是开着的,我用的是 win7 + MySQL5.5,数据库在本地。

1.%可以用cmd开启数据库,启动命令是:. visit 1point3acres.com for more.

2.net start mysql55. 1point3acres.com/bbs

3.%关闭命令是:. 鍥磋鎴戜滑@1point 3 acres

4.net stop mysql55

复制代码

使用MySQLdb模块代码示例:

1.# 导入 MySQLdb模块.鏈枃鍘熷垱鑷�1point3acres璁哄潧

2.import MySQLdb

3.# 和服务器建立链接,host是服务器ip,我的MySQL数据库搭建在本机,默认的是127.0.0.1,

4.# 用户、密码、数据库名称对应着照输就行了,默认的端口号是3306,charset是编码方式,

5.# 默认的是utf8(也有可能是gbk,看安装的版本)。

6.conn = MySQLdb.connect(host='127.0.0.1',user='root', passwd='yourPassword', db='dbname', port=3306, charset='utf8')

7.# 建立cursor

8.cur = conn.cursor()

9.# 通过对象cur的execute()方法执行SQL语句

10. cur.execute("select * fromciteRelation where paperName = 'On Random Graph'")

11. # fetchall()方法获得查询结果,返回的是一个list,可以直接这样查询:list[i][j],

12. # i表示查询结果中的第i+1条record,j表示这条记录的第j+1个attribute(别忘了python从0开始计数)

13. list = cur.fetchall() 鏉ユ簮涓€浜�.涓夊垎鍦拌鍧�.

14. # 也可以进行delete,drop,insert,update等操作,比如:

15. sql = "update studentCourseRecordset fail = 1 where studentID = '%s' and semesterID = '%s' and courseID ='%s'" %(studentID,course[0],course[1])

16. cur.execute(sql)

17. # 与查询不同的是,执行完delete,insert,update这些语句后必须执行下面的命令才能成功更新数据库

18. conn.commit()

19. # 一如既往的,用完了之后记得关闭cursor,然后关闭链接

20. cur.close()

21. conn.close()

复制代码

这样就实现了Python和数据库之间的交互。除了MySQL数据库外,python的PyGreSQL模块可以支持postgreSQL数据库,道理类似的。还有,如果你的网页里面包含了中文,设置编码格式会非常的麻烦,需要服务器、Python、数据库和数据库界面采用相同的编码格式才能不出现乱码,如果真的出现了中文乱码的问题,请相信,你不是一个人!!去google一下吧,成千上万的人碰到过这种问题。.1point3acres.com/bbs 关于编码的问题,附一篇我看到的博文<python编码问题总结>:.1point3acres.com/bbs http://www.xprogrammer.com/1258.html 后记: 上面介绍了抓取网页数据的方法,抓取数据只是一小步,如何分析数据就是大学问了,欢迎讨论。 上面有什么地方讲不清楚的,欢迎交流。 特别注意: 大规模抓取网站会给网站的服务器带来很大的压力,尽量选择服务器相对轻松的时段(比如凌晨)。网站很多,不要拿一亩三分地来做试验。 Python的time模块的sleep()方法可以让程序暂停一段时间,比如time.sleep(1)让程序运行到这里的时候暂停1秒。适时地暂停可以缓解服务器的压力,也可以保护自己的硬盘,正好码久了睡个觉,或者去趟gym,结果就出来了。 更新: 2014年2月15日,更改了几处打字错误;添加了相关课程链接;增加了udacity CS101的介绍;增加了MySQLdb模块的介绍。 2014年2月16日,增加了介绍编码方式的博文链接。

原文发布于微信公众号 - PPV课数据科学社区(ppvke123)

原文发表时间:2014-10-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏农夫安全

浅说驱动程序的加载过程

在开始之前,首先简要介绍一下本文的主题,这篇文章是关于将内核模块加载到操作系统内核的方法的介绍。所谓“内核模块”,指的便是通常所说的驱动程序。不过因为加载到内核...

3509
来自专栏Google Dart

AngularDart4.0 英雄之旅-教程-06服务 顶

不是一遍又一遍复制和粘贴相同的代码,而是创建一个可重用的数据服务,并将其注入到需要它的组件中。 使用单独的服务可使组件保持精简并专注于支持视图,并使用模拟服务对...

691
来自专栏Ryan Miao

做项目中没经验遇到的各种问题

1.java基础不牢,关于对象和类的生命周期等不明白 在做app登陆token验证的时候。我设计一个tokenutil中添加一个成员变量map,每次登陆成功,将...

3008
来自专栏Albert陈凯

手把手教你用python抓取网页导入模块 urllib2随便查询一篇文章,比如On random graph。对每一个查询googlescholar都有一个url,这个url形成的规则是要自己分析的。

http://www.1point3acres.com/bbs/thread-83337-1-1.html **前言: ** 数据科学越来越火了,网页是数据...

3247
来自专栏BeJavaGod

通过spring实现javamail的那些事儿

以前很早的时候大家都用javamail实现发送邮件的功能,而且我们也一直沿用至今,代码拷过来用用就行了,现在我们改为用spring来实现,这样一来减少代码的复杂...

2964
来自专栏Albert陈凯

终极 Shell-MacTalk-池建强的随想录Customize to your needs…

终极 Shell Posted on 2013 年 7 月 23 日 http://macshuo.com/?p=676 ? zsh 在开始今天的 Mac...

3308
来自专栏菩提树下的杨过

[转自Scott]ASP.NET MVC框架(第四部分): 处理表单编辑和提交场景

英文原文地址:http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-mvc-framework-p...

3526
来自专栏Java技术栈

扫盲,为什么分布式一定要有Redis?

考虑到绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体缺乏一个认知...

1573
来自专栏有趣的Python

最新Django2.0.1在线教育零基础到上线教程(十三)xadmin的进阶开发

演示地址: http://mxonline.mtianyan.cn 教程仓库地址1: https://github.com/mtianyan/DjangoGe...

40711
来自专栏应用案例

IT面试干货:PHP面试题汇总及答案

随着近两年来互联网潮流的发展,不少人选择php程序开发的学习。所以今天济南IT培训优就业的老师将与大家一起聊一聊PHP面试会问什么?、 ? PHP程序员经典面试...

3779

扫码关注云+社区

领取腾讯云代金券