最详细的Python爬虫入门教程,一篇文章入门爬虫不是儿戏!

0×00 介绍

0×01 要求

0×02 你能学到什么?

0×03 知识补充

0×04 最简单的开始

0×05 更优雅的解决方案

0×06 url合法性判断

0×07 总结与预告

0×00 介绍

学习Python中有不明白推荐加入交流群
号:548377875
群里有志同道合的小伙伴,互帮互助,
群里有不错的学习教程!

爬虫技术是数据挖掘,测试技术的重要的组成部分,是搜索引擎技术的核心。

但是作为一项普通的技术,普通人同样可以用爬虫技术做很多很多的事情,比如:你想了解一下某网所有关于爬虫技术的文章,你就可以编写爬虫去对文章进行搜索,解析。比如你想获得淘宝某类商品的价格,你可以编写爬虫自动搜索某类商品,然后获取信息,得到自己想要的结果,每天定时爬一下自己就可以决定在什么时候低价的时候买下心仪的商品了。或者说自己想收集某类信息集合成自己的数据库,但是手动复制粘贴特别的麻烦,这时候爬虫技术就可以帮上大忙了对不对?

0×01 要求(私信小编007即可获取大量Python学习资料)

那么本系列文章旨在普及爬虫技术,当然不是那种直接拿来爬虫框架来说明的。在本系列文章中,笔者尽力从简到难,简明地介绍爬虫的各种要素,怎么样快速编写对自己有用的代码。但是对读者有一定小小的要求:看得懂python代码,然后自己能动手实践一些,除此之外,还要对html元素有一定的了解。

0×02 你能学到什么?

当然爬虫的文章在网上很容易找到,但是精致,系统地讲解的文章还是比较少,笔者在本文和今后的文章将介绍关于爬虫的各种各样的知识:

大致上,本文的写作顺序是单机爬虫到分布式爬虫,功能实现到整体设计,从微观到宏观。

1. 简单模块编写简单爬虫

2. 相对优雅的爬虫

3. 爬虫基本理论以及一般方法

4. 简单Web数据挖掘

5. 动态web爬虫(可以处理js的爬虫)

6. 爬虫的数据存储

7. 多线程与分布式爬虫设计

如果有读者想找一些爬虫的入门书籍来看,我推荐《web scraping with python》,这本书是英文版目前没有中文译本,但是网上有爱好者在翻译,有兴趣的读者可以了解一下。

0×03 知识补充

在这里的知识补充我其实是要简单介绍目前主流的几种爬虫编写用的模块:

Htmllib(sgmllib),这个模块是非常古老的一个模块,偏底层,实际就是简单解析html文档而已,不支持搜索标签,容错性也比较差,这里指的提醒的是,如果传入的html文档没有正确结束的话,这个模块是不会解析的,直到正确的数据传入或者说强行关闭。

BeautifulSoup,这个模块解析html非常专业,具有很好的容错性,可以搜索任意标签,自带编码处理方案。

Selenium,自动化web测试方案解决者,类似BeautifulSoup,但是不一样的是,selenium自带了js解释器,也就是说selenium配合浏览器可以用来做动态网页的爬取,分析,挖掘。

Scrapy框架:一个专业的爬虫框架(单机),有相对完整的解决方案。

API爬虫:这里大概都是需要付费的爬虫API,比如google,twitter的解决方案,就不在介绍。

笔者在文章中只会出现前三种方式来做爬虫编写。

0×04 最简单的开始

最开始的一个例子,我将会先介绍最简单的模块,编写最简单的单页爬虫:

Urllib这个模块我们这里用来获取一个页面的html文档,具体的使用是,

Web = urllib.urlopen(url)

Data = Web.read()

要注意的是,这是py2的写法,py3是不一样的。

Smgllib这个库是htmllib的底层,但是也可以提供一个对html文本的解析方案,具体的使用方法是:

1. 自定义一个类,继承sgmllib的SGMLParser;

2. 复写SGMLParser的方法,添加自己自定义的标签处理函数

3. 通过自定义的类的对象的.feed(data)把要解析的数据传入解析器,然后自定义的方法自动生效。

import urllibimport sgmllib 

class handle_html(sgmllib.SGMLParser): #unknown_starttag这个方法在任意的标签开始被解析时调用 #tag为标签名 #attrs表示标签的参赛 def unknown_starttag(self, tag, attrs): print "-------"+tag+" start--------" print attrs #unknown_endtag这个方法在任意标签结束被解析时被调用 def unknown_endtag(self, tag): print "-------"+tag+" end----------"

web =urllib.urlopen("http://freebuf.com/")web_handler = handle_html()#数据传入解析器web_handler.feed(web.read())

短短十几行代码,最简单的单页面爬虫就完成了,以下是输出的效果。我们可以看到标签开始和结束都被标记了。然后同时打印出了每一个参数。

接下来我们可以使用这种底层的解析方式来做个基础的小例子:

下面这个小例子在标签开始的时候检查标签中的attrs属性,解析出所有的参数的href属性,知道的读者都知道这基本是被一个爬虫的必经之路。

import urllibimport sgmllib

class handle_html(sgmllib.SGMLParser):defunknown_starttag(self, tag, attrs): #这里利用try与except来避免报错。 #但是并不推荐这样做, #对于这种小脚本虽然无伤大雅,但是在实际的项目处理中,#这种做法存在很大的隐患 try: for attr in attrs: if attr[0] == "href": printattr[0]+":"+attr[1].encode(‘utf-8‘) except: pass

web =urllib.urlopen("http://freebuf.com/")web_handler = handle_html()web_handler.feed(web.read())

解析结果为:

我们发现在解析出的href种,存在一些不和谐的因素,比如JavaScript的出现,比如其他域名的出现,或者有些读者说的,url有重复。实际上,这是对于我们的FreeBuf站来说,但是对于互联网上的各种复杂环境来说,上面的考虑是完全不够的。关于这一点我们稍后再做讨论。

但是笔者并不计划就用这个方法来把我们的问题处理完全。因为我们有更优雅的解决方案。

0×05 更优雅的解决方案

当然我说的时BeautifulSoup,为什么选用这个模块呢?笔者私认为这个模块解析html非常专业,这里简称bs4,读过bs4的读者都很清楚。实际上beautifulsoup并不只是简单的解析html文档,实际上里面大有玄机:五种解析器自动选择或者手动指定,每个解析器的偏重方向都不一样,有的偏重速度,有的偏重正确率。自动识别html文档的编码,并且给出非常完美的解决方案,支持css筛选,各种参数的方便使用。

BeautifulSoup的一般使用步骤:

1. 导入beatifulsoup库 :from bs4 import BeautifulSoup

2. 传入数据,建立对象: soup = BeautifulSoup(data),

3. 操作soup,完成需求解析。

下面我们来看具体的代码实例:

from bs4 import BeautifulSoupimport urllibimport reweb =urllib.urlopen("http://freebuf.com/")soup = BeautifulSoup(web.read())tags_a =soup.findAll(name="a",attrs={‘href‘:re.compile("^https?://")})for tag_a in tags_a:printtag_a["href"]

这一段与sgmllib的第二短代码相同功能,但写起来就更加的优雅。然后还引入了正则表达式,稍微过滤下链接的表达式,过滤掉了JavaScript字样,显然看起来简炼多了:

简单解释一下上面的warning:

UserWarning: No parser was explicitlyspecified, so I’m using the best available HTML parser for this system(“html.parser”). This usually isn’t a problem, but if you run thiscode on another system, or in a different virtual environment, it may use adifferent parser and behave differently.

To get rid of this warning, change this:

BeautifulSoup([your markup])

to this:

BeautifulSoup([your markup],”html.parser”)

上面的内容是说:没有特别指明解析器,bs4使用了它认为最好的解析器html.parser,这一般不会出问题,但是如果你在不同的环境下运行,可能解析器是不一样的。要移除这个warning可以修改你的beautifulsoup选项改成BeautifulSoup(data, “html.parser”)

这个warning表明了bs4的自动选择解析器来解析的特性。

0×06 url和合法性判断

url与uri其实是一个东西,如果但是我们更多的不提uri,那么我们来说一下关于url的处理:如果说像我们一开始那样做的话,我们手动,或者通过正则去分析每一个url,我们要考虑url的各种结构,比如下面这些例子:

path?ss=1#archhttp://freebuf.com/geek?ss=1path/mejavascript:void(0)/freebuf.com/s/s/s/sssfadea://ssss.sspath?ss=1&s=1ftp://freeme.com/ss/s/spath?ss=1#arch//freebuf.com/s/s/s/https://freebuf.com:443/geek?id=1#sid//freebuf.com/s/s/s

我们大概就是要处理这么多的不同形式的url,这些都是在网页上非常有可能出现的url,那么,那么我们怎么判断这些的合法性呢?

先以//分开,左边时协议+‘:’,右边到第一个’/’是域名,域名后面时路径,?后面时参数,#后面是锚点。

这么分析来的话写代码判断应该不是一个特别困难的事情,但是我们并没有必要每次都去写代码解决这个问题啊,毕竟我们在使用python,这些事情并不需要自己来做,

其实我个人觉得这个要得益于python强大的模块:urlparser,这个模块就是把我们上面的url分析思路做了实现,用法也是pythonic:

import urlparseurl = set()url.add(‘javascript:void(0)‘)url.add(‘http://freebuf.com/geek‘)url.add(‘https://freebuf.com:443/geek?id=1#sid‘)url.add(‘ftp://freeme.com/ss/s/s‘)url.add(‘sssfadea://ssss.ss‘)url.add(‘//freebuf.com/s/s/s‘)url.add(‘/freebuf.com/s/s/s/‘)url.add(‘//freebuf.com/s/s/s/‘)url.add(‘path/me‘)url.add(‘path?ss=1‘)url.add(‘path?ss=1&s=1‘)url.add(‘path?ss=1#arch‘)url.add(‘?ss=1‘)url.add(‘#arch‘)for item in url: print item o= urlparse.urlparse(item) print o print

然后执行代码,我们可以看一下具体的解析结果:

import urlparseurl = set()url.add(‘javascript:void(0)‘)url.add(‘http://freebuf.com/geek‘)url.add(‘https://freebuf.com:443/geek?id=1#sid‘)url.add(‘ftp://freeme.com/ss/s/s‘)url.add(‘sssfadea://ssss.ss‘)url.add(‘//freebuf.com/s/s/s‘)url.add(‘/freebuf.com/s/s/s/‘)url.add(‘//freebuf.com/s/s/s/‘)url.add(‘path/me‘)url.add(‘path?ss=1‘)url.add(‘path?ss=1&s=1‘)url.add(‘path?ss=1#arch‘)url.add(‘?ss=1‘)url.add(‘#arch‘)for item in url: print item o= urlparse.urlparse(item) print o printpath?ss=1#archParseResult(scheme=‘‘, netloc=‘‘,path=‘path‘, params=‘‘, query=‘ss=1‘, fragment=‘arch‘)

http://freebuf.com/geekParseResult(scheme=‘http‘,netloc=‘freebuf.com‘, path=‘/geek‘, params=‘‘, query=‘‘, fragment=‘‘)

?ss=1ParseResult(scheme=‘‘, netloc=‘‘, path=‘‘,params=‘‘, query=‘ss=1‘, fragment=‘‘)

path/meParseResult(scheme=‘‘, netloc=‘‘,path=‘path/me‘, params=‘‘, query=‘‘, fragment=‘‘)

javascript:void(0)ParseResult(scheme=‘javascript‘, netloc=‘‘,path=‘void(0)‘, params=‘‘, query=‘‘, fragment=‘‘)

/freebuf.com/s/s/s/ParseResult(scheme=‘‘, netloc=‘‘, path=‘/freebuf.com/s/s/s/‘,params=‘‘, query=‘‘, fragment=‘‘)

sssfadea://ssss.ssParseResult(scheme=‘sssfadea‘,netloc=‘ssss.ss‘, path=‘‘, params=‘‘, query=‘‘, fragment=‘‘)

path?ss=1&s=1ParseResult(scheme=‘‘, netloc=‘‘,path=‘path‘, params=‘‘, query=‘ss=1&s=1‘, fragment=‘‘)

ftp://freeme.com/ss/s/sParseResult(scheme=‘ftp‘,netloc=‘freeme.com‘, path=‘/ss/s/s‘, params=‘‘, query=‘‘, fragment=‘‘)

path?ss=1ParseResult(scheme=‘‘, netloc=‘‘,path=‘path‘, params=‘‘, query=‘ss=1‘, fragment=‘‘)

#archParseResult(scheme=‘‘, netloc=‘‘, path=‘‘,params=‘‘, query=‘‘, fragment=‘arch‘)

//freebuf.com/s/s/s/ParseResult(scheme=‘‘,netloc=‘freebuf.com‘, path=‘/s/s/s/‘, params=‘‘, query=‘‘, fragment=‘‘)

https://freebuf.com:443/geek?id=1#sidParseResult(scheme=‘https‘,netloc=‘freebuf.com:443‘, path=‘/geek‘, params=‘‘, query=‘id=1‘,fragment=‘sid‘)

//freebuf.com/s/s/sParseResult(scheme=‘‘,netloc=‘freebuf.com‘, path=‘/s/s/s‘, params=‘‘, query=‘‘, fragment=‘‘)

在urlparser返回的对象中我们可以直接以索引的方式拿到每一个参数的值。那么我们这里就有索引表了:

这张表的用法,

o = urlparse.urlparse(url)

o[0]表示scheme

o[1]表示netloc

……

以此类推。

我们发现:

如果scheme和netloc都同时为空的话,该url可能是当前url+path

如果scheme不为空但是netloc为空的话,该url不合法

如果scheme为空但是netloc不为空的话,不一定不合法,要具体分析,一般情况下是http

如果只存在fragment或者query的话,该url为当前的url+query[+fragment]

……

那么根据上面的规则,我们基本可以把无关的url或者不是url排除掉,或者恢复完整的url

0×07 总结与预告

本章中我们一起探究了一个简单爬虫的实现,然后稍微讨论了一下如何处理页面的url。相信读者读完本文的时候已经有了一定的对爬虫的基础认识,但是要知道,只了解到这种程度还不能说了解爬虫,这只是冰山一角。

在下一节中,我们将学到下面的知识:

1、爬虫道德与爬虫的理论知识

2、sitemap爬虫

3、简单web数据处理

原文地址:https://www.cnblogs.com/kongshouyisuiyue/p/9595424.html

时间: 2024-10-12 09:10:18

最详细的Python爬虫入门教程,一篇文章入门爬虫不是儿戏!的相关文章

影视动画 Premiere视频教程 AE CS5专业入门教程 绘声绘影X6入门提高 3DS MAX三维动画教程

热门推荐电脑办公计算机基础知识教程 Excel2010基础教程 Word2010基础教程 PPT2010基础教程 五笔打字视频教程 Excel函数应用教程 Excel VBA基础教程 WPS2013表格教程 更多>平面设计PhotoshopCS5教程 CorelDRAW X5视频教程 Photoshop商业修图教程 Illustrator CS6视频教程 更多>室内设计3Dsmax2012教程 效果图实例提高教程 室内设计实战教程 欧式效果图制作实例教程 AutoCAD2014室内设计 Aut

影视动画Premiere视频教程 AE CS5专业入门教程 绘声绘影X6入门提高 3DS MAX三维动画教程

热门推荐电脑办公计算机基础知识教程 Excel2010基础教程 Word2010基础教程 PPT2010基础教程 五笔打字视频教程 Excel函数应用教程 Excel VBA基础教程 WPS2013表格教程 更多>平面设计PhotoshopCS5教程 CorelDRAW X5视频教程 Photoshop商业修图教程 Illustrator CS6视频教程 更多>室内设计3Dsmax2012教程 效果图实例提高教程 室内设计实战教程 欧式效果图制作实例教程 AutoCAD2014室内设计 Aut

spring mvc入门教程(快速入门,深入分析)

目录 一.前言 二.spring mvc 核心类与接口 三.spring mvc 核心流程图 四.spring mvc DispatcherServlet说明 五.spring mvc 父子上下文的说明 六.springMVC-mvc.xml 配置文件片段讲解 七.spring mvc 如何访问到静态的文件,如jpg,js,css 八.spring mvc 请求如何映射到具体的Action中的方法 九.spring mvc 中的拦截器: 十.spring mvc 如何使用拦截器 十一.sprin

storm入门教程 第一章 前言

转自:http://blog.linezing.com/?p=1847 storm:http://www.cnblogs.com/panfeng412/tag/Storm/ http://blog.linezing.com/?cat=92 1.1   实时流计算 互联网从诞生的第一时间起,对世界的最大的改变就是让信息能够实时交互,从而大大加速了各个环节的效率.正因为大家对信息实时响应.实时交互的需求,软件行业除了个人操作系统之外,数据库(更精确的说是关系型数据库)应该是软件行业发展最快.收益最为

storm入门教程 第一章 前言[转]

1.1   实时流计算 互联网从诞生的第一时间起,对世界的最大的改变就是让信息能够实时交互,从而大大加速了各个环节的效率.正因为大家对信息实时响应.实时交互的需求,软件行业除了个人操作系统之外,数据库(更精确的说是关系型数据库)应该是软件行业发展最快.收益最为丰厚的产品了.记得十年前,很多银行别说实时转账,连实时查询都做不到,但是数据库和高速网络改变了这个情况. 随着互联网的更进一步发展,从Portal信息浏览型到Search信息搜索型到SNS关系交互传递型,以及电子商务.互联网旅游生活产品等将

学习maven的使用,看到一篇很实用的入门教程(菜鸟级入门)

一.前言         早就知道maven 在java 项目的管理方面名声显赫,于是就想着学习掌握之,于是查阅了大量文档.发现这些文档的作者都是java 的大腕,大多都是站在掌握了一定maven 基础的角度上进行介绍,让我这初学者看的云里雾里不知所云.于是又去查看maven 的官方网站,总算是有所了解,但一旦动手实际操作却又雾里看花.唉,没办法,就只有一遍一遍的动手尝试,经过种 种磨难总算是有一点眉目了.现在就将我的经验写出来,一来避免将来遗忘,二来也给和我一样的菜鸟们提供一点点的方便.呵呵.

[转发]学习maven的使用,看到一篇很实用的入门教程(菜鸟级入门)

一.前言        早就知道maven 在java 项目的管理方面名声显赫,于是就想着学习掌握之,于是查阅了大量文档.发现这些文档的作者都是java 的大腕,大多都是站在掌握了一定maven 基础的角度上进行介绍,让我这初学者看的云里雾里不知所云.于是又去查看maven 的官方网站,总算是有所了解,但一旦动手实际操作却又雾里看花.唉,没办法,就只有一遍一遍的动手尝试,经过种种磨难总算是有一点眉目了.现在就将我的经验写出来,一来避免将来遗忘,二来也给和我一样的菜鸟们提供一点点的方便.呵呵.本文

Dart入门?一篇文章就够了!

近期公司准备启动新项目,经过技术团队一番调研,决定采用 Flutter 来开发第一版App,故作此文,常来回顾温习.由于项目采用敏捷开发模式,故本文主要总结和记录 Dart 常用语法,更多高级和生僻用法将在后面开发过程中不定期更新. First of all 在我们正式接触 Dart 语法之前,需要铭记以下内容,这将会对后续 Dart 语法的学习.理解和应用有很大帮助: 万物皆对象, 每个对象都是一个类的实例.在 Dart 中,甚至连数字.方法和 null 都是对象,并且所有的对象都继承于 Ob

Storm入门教程 第二章 构建Topology[转]

2.1 Storm基本概念 在运行一个Storm任务之前,需要了解一些概念: Topologies Streams Spouts Bolts Stream groupings Reliability Tasks Workers Configuration Storm集群和Hadoop集群表面上看很类似.但是Hadoop上运行的是MapReduce jobs,而在Storm上运行的是拓扑(topology),这两者之间是非常不一样的.一个关键的区别是: 一个MapReduce job最终会结束,