read( )方法

下面再通过一个实例来看看:

代码详情

运行结果如下:

运行结果输出

可见,前两个输出分别输出了响应的状态码和响应的头信息,最后一个输出通过getheader( )方法传递一个参数Server获取了响应头中的Server值,结果是nginx,意思是服务器使用Nginx搭建的。

利用最基本的urlopen( )方法,可以完成最基本的简单网页的GET请求抓取。

如果想给链接传递一些参数,该怎么实现呢?首先看一个urlopen( )函数的API:

urllib.request.urlopen(url, data=None,[timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

可以发现,除了第一个参数可以传递URL之外,我们还可以传递其他内容,比如data(附加数据)、timeout(超时时间)等。

下面我们详细说明下这几个参数的用法。

data参数

data参数是可选的。如果要添加该参数,需要使用bytes( )方法将参数转化为字节流编码格式的内容,即bytes类型。另外,如果传递了这个参数,则它的请求方式就不再是GET方式,而是POST方式。

下面用实例来看一下:


这里我们传递了一个参数word,值是hello。它需要被转码成bytes(字节流)类型。其中转字节流采用了bytes( )方法,该方法的第一个参数需要是str(字符串)类型,需要用urllib.parse模块里的urlencode( )方法来参数字典转化为字符串;第二个参数指定编码格式,这里指定为utf8。这里请求的站点是httpbin.org,它可以提供HTTP请求测试。我们用图中的链接来测试POST请求,它可以输出请求的一些信息,其中包含我们传递的data参数。运行结果如下:

运行结果

我们传递的参数出现在了form字段中,这表明是模拟表单提交的方式,以POST方式传输数据。

timeout参数

timeout参数用于设置超时时间,单位为秒,意思就是如果请求超出了设置的这个时间,还没有得到响应,就会抛出异常。如果不指定该参数,就会使用全局默认时间。它支持HTTP、HTTPS、FTP请求。

下面我们用实例来看一下:

详细代码

运行结果如下:

结果

这里我们设置超时时间是0.1秒。程序0.1秒之后,服务器依然没有响应,于是抛出了URLError异常。该异常属于urllib.error模块,错误原因是超时。

因此,可以通过设置这个超时时间来控制一个网页如果长时间未响应,就跳过它的抓取。这可以利用try-except语句来实现,相关代码如下:

代码

这里我们请求了图中urlopen( )中的测试链接,设置超时时间为0.1秒,然后捕获了URLError异常,接着判断异常是socket.timeout类型(意思就是超时异常),从而得出它确实是因为超时而报错打印输出了:Time out!我们可以看到运行结果和我们预期的是一样的:

结果展示

通过设置timeout这个参数来实现超时处理,有时还是很有用的。

其他参数

除了data参数和timeout参数外,还有context参数,它必须是ssl.SSLContext类型,用来指定SSL设置。此外,cafile和capath这两个参数分别指定CA证书和它的路径,它在请求HTTPS链接时会有用。cadefault参数现在已经弃用了,其默认值为False。