python网络爬虫.docx
- 文档编号:29610538
- 上传时间:2023-07-25
- 格式:DOCX
- 页数:48
- 大小:39.63KB
python网络爬虫.docx
《python网络爬虫.docx》由会员分享,可在线阅读,更多相关《python网络爬虫.docx(48页珍藏版)》请在冰豆网上搜索。
python网络爬虫
1、网络爬虫的定义
网络爬虫,即WebSpider,是一个很形象的名字。
把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛。
网络蜘蛛是通过网页的链接地址来寻找网页的。
从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,
然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。
如果把整个互联网当成一个网站,那么网络蜘蛛就可以用这个原理把互联网上所有的网页都抓取下来。
这样看来,网络爬虫就是一个爬行程序,一个抓取网页的程序。
网络爬虫的基本操作是抓取网页。
那么如何才能随心所欲地获得自己想要的页面
我们先从URL开始。
2、浏览网页的过程
抓取网页的过程其实和读者平时使用IE浏览器浏览网页的道理是一样的。
比如说你在浏览器的地址栏中输入这个地址。
打开网页的过程其实就是浏览器作为一个浏览的“客户端”,向服务器端发送了一次请求,把服务器端的文件“抓”到本地,再进行解释、展现。
HTML是一种标记语言,用标签标记内容并加以解析和区分。
浏览器的功能是将获取到的HTML代码进行解析,然后将原始的代码转变成我们直接看到的网站页面。
3、URI的概念和举例
简单的来讲,URL就是在浏览器端输入的这个字符串。
在理解URL之前,首先要理解URI的概念。
什么是URI
Web上每种可用的资源,如HTML文档、图像、视频片段、程序等都由一个通用资源标志符(UniversalResourceIdentifier,URI)进行定位。
URI通常由三部分组成:
①访问资源的命名机制;
②存放资源的主机名;
③资源自身的名称,由路径表示。
我们可以这样解释它:
①这是一个可以通过HTTP协议访问的资源,
②
③通过路径“/html/html40”访问。
4、URL的理解和举例
URL是URI的一个子集。
它是UniformResourceLocator的缩写,译为“统一资源定位符”。
通俗地说,URL是Internet上描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上。
采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。
URL的格式由三部分组成:
①第一部分是协议(或称为服务方式)。
②第二部分是存有该资源的主机IP地址(有时也包括端口号)。
③第三部分是主机资源的具体地址,如目录和文件名等。
第一部分和第二部分用“:
tml)是在目录/channel下的。
这是中国人民日报的一台计算机。
超级文本文件(文件类型为.html)是在目录/talk下的。
这是瑞得聊天室的地址,可由此进入瑞得聊天室的第1室。
2.文件的URL用URL表示文件时,服务器方式用file表示,后面要有主机IP地址、文件的存取路径(即目录)和文件名等信息。
有时可以省略目录和文件名,但“/”符号不能省略。
爬虫最主要的处理对象就是URL,它根据URL地址取得所需要的文件内容,然后对它进行进一步的处理。
因此,准确地理解URL对理解网络爬虫至关重要。
所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。
?
类似于使用程序模拟IE浏览器的功能,把URL作为HTTP请求的内容发送到服务器端,然后读取服务器端的响应资源。
在Python中,我们使用urllib2这个组件来抓取网页。
urllib2是Python的一个获取URLs(UniformResourceLocators)的组件。
它以urlopen函数的形式提供了一个非常简单的接口。
最简单的urllib2的应用代码只需要四行。
我们新建一个文件来感受一下urllib2的作用:
[python]
1.importurllib2
2.response=()
3.html=()
4.printhtml
按下F5可以看到运行的结果:
我们可以打开XX主页,右击,选择查看源代码(火狐OR谷歌浏览器均可),会发现也是完全一样的内容。
也就是说,上面这四行代码将我们访问XX时浏览器收到的代码们全部打印了出来。
这就是一个最简单的urllib2的例子。
除了"",URL同样可以使用"ftp:
","file:
"等等来替代。
HTTP是基于请求和应答机制的:
客户端提出请求,服务端提供应答。
urllib2用一个Request对象来映射你提出的HTTP请求。
在它最简单的使用形式中你将用你要请求的地址创建一个Request对象,
通过调用urlopen并传入Request对象,将返回一个相关请求response对象,
这个应答对象如同一个文件对象,所以你可以在Response中调用.read()。
我们新建一个文件来感受一下:
[python]
1.importurllib2
2.req=()
3.response=(req)
4.the_page=()
5.printthe_page
可以看到输出的内容和test01是一样的。
urllib2使用相同的接口处理所有的URL头。
例如你可以像下面那样创建一个ftp请求。
[python]
1.req=()
在HTTP请求时,允许你做额外的两件事。
1.发送data表单数据
这个内容相信做过Web端的都不会陌生,
有时候你希望发送一些数据到URL(通常URL与CGI[通用网关接口]脚本,或其他WEB应用程序挂接)。
在HTTP中,这个经常使用熟知的POST请求发送。
这个通常在你提交一个HTML表单时由你的浏览器来做。
并不是所有的POSTs都来源于表单,你能够使用POST提交任意的数据到你自己的程序。
一般的HTML表单,data需要编码成标准形式。
然后做为data参数传到Request对象。
编码工作使用urllib的函数而非urllib2。
我们新建一个文件来感受一下:
[python]
1.importurllib
2.importurllib2
3.url=
4.values={'name':
'WHY',
5.'location':
'SDU',
6.'language':
'Python'}
7.data=(values)#编码工作
8.req=(url,data)#发送请求同时传data表单
9.response=(req)#接受反馈的信息
10.the_page=()#读取反馈的内容
如果没有传送data参数,urllib2使用GET方式的请求。
GET和POST请求的不同之处是POST请求通常有"副作用",
它们会由于某种途径改变系统状态(例如提交成堆垃圾到你的门口)。
Data同样可以通过在Get请求的URL本身上面编码来传送。
[python]
1.importurllib2
2.importurllib
3.data={}
4.data['name']='WHY'
5.data['location']='SDU'
6.data['language']='Python'
7.url_values=(data)
8.printurl_values
9.name=Somebody+Here&language=Python&location=Northampton
10.url=
11.full_url=url+''+url_values
12.data=(full_url)
这样就实现了Data数据的Get传送。
2.设置Headers到http请求
有一些站点不喜欢被程序(非人为访问)访问,或者发送不同版本的内容到不同的浏览器。
默认的urllib2把自己作为“Python-urllib/”(x和y是Python主版本和次版本号,例如Python-urllib/,这个身份可能会让站点迷惑,或者干脆不工作。
浏览器确认自己身份是通过User-Agent头,当你创建了一个请求对象,你可以给他一个包含头数据的字典。
下面的例子发送跟上面一样的内容,但把自身模拟成InternetExplorer。
[python]
1.importurllib
2.importurllib2
3.url=
4.user_agent='Mozilla/(compatible;MSIE;WindowsNT)'
5.values={'name':
'WHY',
6.'location':
'SDU',
7.'language':
'Python'}
8.headers={'User-Agent':
user_agent}
9.data=(values)
10.req=(url,data,headers)
11.response=(req)
12.the_page=()
先来说一说HTTP的异常处理问题。
当urlopen不能够处理一个response时,产生urlError。
不过通常的PythonAPIs异常如ValueError,TypeError等也会同时产生。
HTTPError是urlError的子类,通常在特定HTTPURLs中产生。
?
通常,URLError在没有网络连接(没有路由到特定服务器),或者服务器不存在的情况下产生。
这种情况下,异常同样会带有"reason"属性,它是一个tuple(可以理解为不可变的数组),
包含了一个错误号和一个错误信息。
我们建一个来感受一下异常的处理:
[python]
1.importurllib2
2.req=()
3.try:
(req)
4.except,e:
5.print
按下F5,可以看到打印出来的内容是:
[Errno11001]getaddrinfofailed
也就是说,错误号是11001,内容是getaddrinfofailed
服务器上每一个HTTP应答对象response包含一个数字"状态码"。
有时状态码指出服务器无法完成请求。
默认的处理器会为你处理一部分这种应答。
例如:
假如response是一个"重定向",需要客户端从别的地址获取文档,urllib2将为你处理。
其他不能处理的,urlopen会产生一个HTTPError。
典型的错误包含"404"(页面无法找到),"403"(请求禁止),和"401"(带验证请求)。
HTTP状态码表示HTTP协议所返回的响应的状态。
比如客户端向服务器发送请求,如果成功地获得请求的资源,则返回的状态码为200,表示响应成功。
如果请求的资源不存在,则通常返回404错误。
HTTP状态码通常分为5种类型,分别以1~5五个数字开头,由3位整数组成:
------------------------------------------------------------------------------------------------
200:
请求成功处理方式:
获得响应的内容,进行处理
201:
请求完成,结果是创建了新资源。
新创建资源的URI可在响应的实体中得到处理方式:
爬虫中不会遇到
202:
请求被接受,但处理尚未完成处理方式:
阻塞等待
204:
服务器端已经实现了请求,但是没有返回新的信息。
如果客户是用户代理,则无须为此更新自身的文档视图。
处理方式:
丢弃
300:
该状态码不被HTTP/的应用程序直接使用,只是作为3XX类型回应的默认解释。
存在多个可用的被请求资源。
处理方式:
若程序中能够处理,则进行进一步处理,如果程序中不能处理,则丢弃301:
请求到的资源都会分配一个永久的URL,这样就可以在将来通过该URL来访问此资源处理方式:
重定向到分配的URL302:
请求到的资源在一个不同的URL处临时保存处理方式:
重定向到临时的URL
304请求的资源未更新处理方式:
丢弃
400非法请求处理方式:
丢弃
401未授权处理方式:
丢弃
403禁止处理方式:
丢弃
404没有找到处理方式:
丢弃
5XX回应代码以“5”开头的状态码表示服务器端发现自己出现错误,不能继续执行请求处理方式:
丢弃
------------------------------------------------------------------------------------------------
HTTPError实例产生后会有一个整型'code'属性,是服务器发送的相关错误号。
当一个错误号产生后,服务器返回一个HTTP错误号,和一个错误页面。
你可以使用HTTPError实例作为页面返回的应答对象response。
这表示和错误属性一样,它同样包含了read,geturl,和info方法。
我们建一个来感受一下:
[python]
1.importurllib2
2.req=()
3.try:
4.(req)
5.except,e:
6.print
7.#print()
按下F5可以看见输出了404的错误码,也就说没有找到这个页面。
所以如果你想为HTTPError或URLError做准备,将有两个基本的办法。
推荐使用第二种。
我们建一个来示范一下第一种异常处理的方案:
[python]
1.fromurllib2importRequest,urlopen,URLError,HTTPError
2.req=Request()
3.try:
4.response=urlopen(req)
5.exceptHTTPError,e:
6.print'Theservercouldn\'tfulfilltherequest.'
7.print'Errorcode:
',
8.exceptURLError,e:
9.print'Wefailedtoreachaserver.'
10.print'Reason:
',
11.else:
12.print'Noexceptionwasraised.'
13.#everythingisfine
和其他语言相似,try之后捕获异常并且将其内容打印出来。
这里要注意的一点,exceptHTTPError必须在第一个,否则exceptURLError将同样接受到HTTPError。
因为HTTPError是URLError的子类,如果URLError在前面它会捕捉到所有的URLError(包括HTTPError)。
我们建一个来示范一下第二种异常处理的方案:
[python]
1.fromurllib2importRequest,urlopen,URLError,HTTPError
2.req=Request()
3.try:
4.response=urlopen(req)
5.exceptURLError,e:
6.ifhasattr(e,'reason'):
7.print'Wefailedtoreachaserver.'
8.print'Reason:
',
9.elifhasattr(e,'code'):
10.print'Theservercouldn\'tfulfilltherequest.'
11.print'Errorcode:
',
12.else:
13.print'Noexceptionwasraised.'
14.#everythingisfine
在开始后面的内容之前,先来解释一下urllib2中的两个个方法:
infoandgeturl
urlopen返回的应答对象response(或者HTTPError实例)有两个很有用的方法info()和geturl()
():
这个返回获取的真实的URL,这个很有用,因为urlopen(或者opener对象使用的)或许会有重定向。
获取的URL或许跟请求URL不同。
以人人中的一个超级链接为例,
我们建一个来比较一下原始URL和重定向的链接:
[python]
1.fromurllib2importRequest,urlopen,URLError,HTTPError
2.old_url=
3.req=Request(old_url)
4.response=urlopen(req)
5.print'Oldurl:
'+old_url
6.print'Realurl:
'+()
运行之后可以看到真正的链接指向的网址:
():
这个返回对象的字典对象,该字典描述了获取的页面情况。
通常是服务器发送的特定头headers。
目前是实例。
经典的headers包含"Content-length","Content-type",和其他内容。
我们建一个来测试一下info的应用:
[python]
1.fromurllib2importRequest,urlopen,URLError,HTTPError
2.old_url=
3.req=Request(old_url)
4.response=urlopen(req)
5.print'Info():
'
6.print()
运行的结果如下,可以看到页面的相关信息:
下面来说一说urllib2中的两个重要概念:
Openers和Handlers。
:
当你获取一个URL你使用一个opener(一个的实例)。
正常情况下,我们使用默认opener:
通过urlopen。
但你能够创建个性的openers。
:
Openers使用处理器handlers,所有的“繁重”工作由handlers处理。
每个handlers知道如何通过特定协议打开URLs,或者如何处理URL打开时的各个方面。
例如HTTP重定向或者HTTPcookies。
如果你希望用特定处理器获取URLs你会想创建一个openers,例如获取一个能处理cookie的opener,或者获取一个不重定向的opener。
要创建一个opener,可以实例化一个OpenerDirector,
然后调用.add_handler(some_handler_instance)。
同样,可以使用build_opener,这是一个更加方便的函数,用来创建opener对象,他只需要一次函数调用。
build_opener默认添加几个处理器,但提供快捷的方法来添加或更新默认处理器。
其他的处理器handlers你或许会希望处理代理,验证,和其他常用但有点特殊的情况。
install_opener用来创建(全局)默认opener。
这个表示调用urlopen将使用你安装的opener。
Opener对象有一个open方法。
该方法可以像urlopen函数那样直接用来获取urls:
通常不必调用install_opener,除了为了方便。
说完了上面两个内容,下面我们来看一下基本认证的内容,这里会用到上面提及的Opener和Handler。
BasicAuthentication基本验证
为了展示创建和安装一个handler,我们将使用HTTPBasicAuthHandler。
当需要基础验证时,服务器发送一个header(401错误码)请求验证。
这个指定了scheme和一个‘realm’,看起来像这样:
Www-authenticate:
SCHEMErealm="REALM".
例如Www-authenticate:
Basicrealm="cPanelUsers"
客户端必须使用新的请求,并在请求头里包含正确的姓名和密码。
这是“基础验证”,为了简化这个过程,我们可以创建一个HTTPBasicAuthHandler的实例,并让opener使用这个handler就可以啦。
HTTPBasicAuthHandler使用一个密码管理的对象来处理URLs和realms来映射用户名和密码。
如果你知道realm(从服务器发送来的头里)是什么,你就能使用HTTPPasswordMgr。
通常人们不关心realm是什么。
那样的话,就能用方便的HTTPPasswordMgrWithDefaultRealm。
这个将在你为URL指定一个默认的用户名和密码。
这将在你为特定realm提供一个其他组合时得到提供。
我们通过给realm参数指定None提供给add_password来指示这种情况。
最高层次的URL是第一个要求验证的URL。
你传给.add_password()更深层次的URLs将同样合适。
说了这么多废话,下面来用一个例子演示一下上面说到的内容。
我们建一个来测试一下info的应用:
[python]
1.#-*-coding:
utf-8-*-
2.importurllib2
3.#创建一个密码管理者
4.password_mgr=()
5.#添加用户名和密码
6.top_level_url=
7.#如果知道realm,我们可以使用他代替``None``.
8.#(None,top_level_url,username,password)
9.(None,top_level_url,'why','1223')
10.#创建了一个新的handler
11.handler=(password_mgr)
12.#创建"opener"(OpenerDirector实例)
13.opener=(handler)
14.a_url=
15.#使用opener获取一个URL
16.(a_url)
17.#安装opener.
18.#现在所有调用将用我们的opener.
19.(opener)
注意:
以上的例子我们仅仅提供我们的HHTPBasicAuthHandler给build_opener。
默认的openers有正常状况的handlers:
ProxyHandler,UnknownHandler,HTTPHandler,HTTPDefaultErrorHandler,HTTPRedirectHandler,FTPHandler,FileHandler,HTTPErrorProcessor。
代码中的top_level_url实际上可以是完整URL(包含"",以及主机名及可选的端口号)。
也可以是一个“authority”(即主机名和可选的包含端口号)。
例如:
“”or“:
8080”。
后者包含了端口号。
前面说到了urllib2的简单入门,下面整理了一部分urllib2的使用细节。
的设置
urllib2默认会使用环境变量http_proxy来设置HTTPProxy。
如果想在程序中明确控制Proxy而不受环境变量的影响,可以使用代理。
新建test14来实现一个简单的代理Demo:
[python]
1.importurllib2
2.enable_proxy=True
3.proxy_handler=({"http":
})
4.null_proxy_handler=({})
5.ifenable_proxy:
6.opener=(proxy_handler)
7.else:
8.opener=(null_proxy_handler)
9.(opener)
这里要注意的一个细节,使用()会设置urllib2的全局opener。
这样后面的使用会很方便,但不能做更细致的控
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- python 网络 爬虫