Python爬虫之urllib库—爬虫的第一步

第一个爬虫代码的实现我想应该是从urllib开始吧,博主开始学习的时候就是使用urllib库敲了几行代码就实现了简单的爬数据功能,我想大多伙伴们也都是这么过来的。当时的感觉就是:哇,好厉害,短短几行竟然就可以搞定一个看似很复杂的任务,于是就在想这短短的几行代码到底是怎么实现的呢,如何进行更高级复杂的爬取呢?带着这个问题我也就开始了urllib库的学习。

首先不得不提一下爬取数据的过程,弄清楚这到底是怎样一个过程,学习urllib的时候会更方便理解。

爬虫的过程

其实,爬虫的过程和浏览器浏览网页的过程是一样的。道理大家应该都明白,就是当我们在键盘上输入网址点击搜索之后,通过网络首先会经过DNS服务器,分析网址的域名,找到了真正的服务器。然后我们通过HTTP协议对服务器发出GET或POST请求,若请求成功,我们就得到了我们想看到的网页,一般都是用HTML, CSS, JS等前端技术来构建的,若请求不成功,服务器会返回给我们请求失败的状态码,常见到的503,403等。

爬虫的过程亦是如此,通过对服务器发出请求得到HTML网页,然后对下载的网页进行解析,得到我们想要的内容。当然,这是一个爬虫过程的一个概况,其中还有很多细节的东西需要我们处理的,这些在后续会继续与大家分享。

了解了爬虫的基本过程后,就可以开始我们真正的爬虫之旅了。

urllib库

Python有一个内置的urllib库,可谓是爬虫过程非常重要的一部分了。这个内置库的使用就可以完成向服务器发出请求并获得网页的功能,所以也是学习爬虫的第一步了。

博主用的是Python3.x,urllib库的结构相对于Python2.x有一些出入,Python2.x中使用的urllib2和urllib库,而Python3.x中合并成一个唯一的urllib库。

首先,我们来看看Python3.x的urllib库都有什么吧。

博主用的IDE是Pycharm,编辑调试非常方便,很赞。

在控制台下输入如下代码:

>>importurllib

>>dir(urllib)

结果:

['__builtins__','__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__','__path__', '__spec__', 'error', 'parse', 'request', 'response']

可以看到urllib除了以双下划线开头结尾的内置属性外,还有4个重要的属性,分别是error,parse,request,response。

在Python的urllib库中doc开头是这样简短描述的:

Error:“Exception classesraised by urllib.”----就是由urllib举出的exception类

Parse:“Parse (absolute andrelative) URLs.”----解析绝对和相对的URLs

Request:“An extensiblelibrary for opening URLs using a variety of protocols”

----用各种协议打开URLs的一个扩展库

Response:“Response classesused by urllib.”----被urllib使用的response类

这4个属性中最重要的当属request了,它完成了爬虫大部分的功能,我们先来看看request是怎么用的。

request

request请求最简单的操作是用urlopen方法,代码如下

运行结果如下:

b'\n

发现得到的运行结果竟然是乱码!!别着急,这是因为编码的问题,我们只需要将请求的类文件读取再解码就可以了。

修改代码如下:

运行结果:

..

...

得到的就是我们想要的html的网页了,怎么样,简单吧。

下面来介绍一下这个urlopen方法和其中应用的参数。

urlopen

defurlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TI

MEOUT,*, cafile=None, capath=None,

cadefault=False, context=None):

这个urlopen的功能是打开一个URL,可以是一串字符串(如上例子中一样),也可以是Request对象(后面会提到)。它会返回一个类文件对象,并可以针对这个对象进行各种操作(如上例中的read操作,将html全部读出来,后面会介绍其它的几个操作)。

data:是我们要发给服务器请求的额外信息(比如登录网页需要主动填写的用户信息)。如果需要添加data参数,那么是POST请求,默认无data参数时,就是GET请求;

一般来讲,data参数只有在http协议下请求才有意义

data参数被规定为byte object,也就是字节对象

data参数应该使用标准的结构,这个需要使用

data在以后实战中会介绍如何使用

timeout:是选填的内容,定义超时时间,单位是秒,防止请求时间过长,不填就是默认的时间;

cafile:是指向单独文件的,包含了一系列的CA认证 (很少使用,默认即可);

capath:是指向文档目标,也是用于CA认证(很少使用,默认即可);

cafile:可以忽略

context:设置SSL加密传输(很少使用,默认即可);

对返回的类文件对象也可以进行其它操作:

geturl():返回URL,用于看是否有重定向。

result=response.geturl()

结果:

https://www.python.org/

info():返回元信息,例如HTTP的headers。

result=response.info()

结果:

x-xss-protection: 1; mode=block

X-Clacks-Overhead: GNU Terry Pratchett

...

Vary: Cookie

Strict-Transport-Security: max-age=63072000;includeSubDomains

getcode():返回回复的HTTP状态码,成功是200,失败可能是503等,可以用来检查代理IP的可使用性。

result=response.getcode()

结果:

200

Request

classRequest:

def__init__(self, url, data=None, headers={},

origin_req_host=None, unverifiable=False,

method=None):

如上定义,Request是一个类,初始化中包括请求需要的各种参数:

url,data和上面urlopen中的提到的一样。

headers是HTTP请求的报文信息,如User_Agent参数等,它可以让爬虫伪装成浏览器而不被服务器发现你正在使用爬虫。

origin_reg_host, unverifiable, method等不太常用

headers很有用,有些网站设有反爬虫机制,检查请求若没有headers就会报错,因此博主为保证爬虫的稳定性,基本每次都会将headers信息加入进去,这是反爬的简单策略之一。

那么如何找到你所在浏览器的headers呢?

可以通过进入浏览器F12查看到

比如,博主用的Chrome浏览器,按F12->network就可以查看request的headers,可以把这个浏览器的headers信息复制下来使用。

下面来看看Request如何使用吧,代码如下:

结果和前面urlopen是一样的,前面提到urlopen除了可以接受指定参数,也可以接受Request类的对象。

在需要headers的情况下,使用Request对象还是很有必要的。

' '里面填写自己浏览器的信息即可。

urllib库的requset属性里面还有很多其它方法,代理、超时、认证、HTTP的POST模式下请求等内容将在下次进行分享,这次主要介绍基本功能。

下面来说说异常,urllib库的error方法。

error

error属性里面主要包括了两个重要的exception类,URLError类和HTTPError类。

URLError类

def__init__(self, reason, filename=None):

self.args=reason,

self.reason=reason

iffilenameis not None:

self.filename=filename

URLError类是OSError的子类,继承OSError,没有自己的任何行为特点,但是将作为error里面所有其它类型的基类使用。

URLError类初始化定义了reason参数,意味着当使用URLError类的对象时,可以查看错误的reason。

HTTPErro类

def__init__(self, url, code, msg, hdrs, fp):

self.code=code

self.msg=msg

self.hdrs=hdrs

self.fp=fp

self.filename=url

HTTPError是URLError的子类,当HTTP发生错误将举出HTTPError。

HTTPError也是HTTP有效回应的实例,因为HTTP协议错误是有效的回应,包括状态码,headers和body。所以看到在HTTPError初始化的时候定义了这些有效回应的参数。

当使用HTTPError类的对象时,可以查看状态码,headers等。

下面我们用一个例子来看一下如何使用这两个exception类。

importurllib.request

importurllib.error

try:

headers={'User_Agent':'Mozilla/5.0 (X11; Ubuntu;

Linux x86_64; rv:57.0) Gecko/20100101

Firefox/57.0'}

response=urllib.request.Request('http://python.org/',

headers=headers)

html=urllib.request.urlopen(response)

result=html.read().decode('utf-8')

excepturllib.error.URLErrorase:

ifhasattr(e,'reason'):

print('错误原因是'+str(e.reason))

excepturllib.error.HTTPErrorase:

ifhasattr(e,'code'):

print('错误状态码是'+str(e.code))

else:

print('请求成功通过。')

以上代码使用了try..exception的结构,实现了简单的网页爬取,当有异常时,如URLError发生时,就会返回reason,或者HTTPError发生错误时就会返回code。异常的增加丰富了爬取的结构,使其更加健壮。

为什么说更加健壮了呢?

不要小看了这些异常的错误,这些异常的错误非常好用,也非常关键。想想看,当你编写一个需要不断自动运行爬取并解析的代码时,你是不希望程序中间被打断而终止的。如果这些异常状态没有设置好,那么就很有可能弹出错误而被终止,但如果设置好了完整的异常,则遇到错误时就会执行发生错误的代码而不被打断(比如向上面代码一样打印错误code等)。

这些打断程序的错误可能是很多种,尤其当你使用代理ip池的时候,会发生很多不同错误,这时异常就起到作用了。

总结

主要介绍了爬虫的过程和urllib的使用和功能,针对爬虫主要介绍了以下的使用方法:

request基本功能, urlopen, Request

error异常的使用

后续将会分享一些request的高级功能,如自定义opener使用代理ip、超时设置、认证等,以及如何POST请求主动发送信息等,也会利用这些内容做一次实战爬取,希望大家能更加理解。

欢迎大家一起来讨论学习,后面内容敬请期待!

本文来自企鹅号 - 全球大搜罗媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JavaEdge

操作系统之文件管理一、文件与文件系统二、文件控制块和文件目录三、文件的物理结构四、文件系统的实现五、文件系统实例(UNIX)六、UNIX文件系统一、文件系统实例(FAT)二、文件操作的实现三、文件系统

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

ASP.NET中常用的优化性能的方法(转贴,Icyer收集整理)

1. 数据库访问性能优化       数据库的连接和关闭   访问数据库资源需要创建连接、打开连接和关闭连接几个操作。这些过程需要多次与数据库交换信息以通过...

25810
来自专栏木子昭的博客

精析Python3实现动态web服务(附服务端源码)如果我们提供一个动态网站服务,至少应考虑以下四点:一个优秀的动态web框架应该是这样的:关于WSGI标准WIGS模型的要点:实现源码小结:

实现一个简单的静态web网站,只需将写好的html页面上传到特定的web服务器软件即可,但静态网页其实和图片没什么区别,每次更新网站内容,都需要重新制作htm...

38112
来自专栏京东技术

开发属于自己的插件 | IDEA & Android Studio插件开发指南

谷轩宇——从事安卓开发,目前效力于通天塔技术开放组是否曾经被ide重复繁琐的操作所困扰,又或者没有心仪的UI控件而难受。那么请阅读这篇文章,掌握idea插件的开...

8182
来自专栏张善友的专栏

替换EnterPrise Library 4.0 缓存应用程序块的CacheManager

缓存是用来提高应用程序性能的常见技术,其实现方式是将常用数据从慢数据源复制到更快的数据源。对于数据驱动的应用程序来说,该技术通常需要将从数据库或 Web 服务检...

1987
来自专栏Python数据科学

Python爬虫之urllib库—爬虫的第一步

第一个爬虫代码的实现我想应该是从urllib开始吧,博主开始学习的时候就是使用urllib库敲了几行代码就实现了简单的爬数据功能,我想大多伙伴们也都是这么过来的...

1111
来自专栏zhangdd.com

linux每天定时备份MySQL数据库并删除五天前的备份文件

Mysql定期备份是一项重要的工作,但人工操作太繁琐,也难避免有所疏漏,使用下面的方法即可让系统定期备份数据。利用系统crontab来定时执行备份文件,按日期对...

1122
来自专栏周明礼的专栏

一步一步带你搭建一个“摩登”的前端开发环境

最近几年也陆续推出了多种不同的js类型系统用于增强js的健壮性,其中像 typescript 就是其中的佼佼者。当然我今天要讲的并不是typescript,而是...

1.5K0
来自专栏生信宝典

一网打进Linux下那些查找命令

查找是我们每天都在做的事情,早上醒来找下手机,出门之前查下公交,坐下之后查下资料,分析数据查下模式。 查找文件,查找信息,查找错误是应用起来更为具体的一些工作,...

55210
来自专栏文武兼修ing——机器学习与IC设计

基于Python的运动计费管理系统动机技术路线规划实现

动机 小伙伴们最近迷恋上羽毛球,组织了个小群,办了公用的运动卡用于开场,考虑不是每次活动都是全员参与,需要一个计费的系统来计算每个人需要交的费用。商讨后决定采用...

3078

扫码关注云+社区

领取腾讯云代金券