Python网络爬虫技术与实战
上QQ阅读APP看书,第一时间看更新

3.2.1 urlopen()函数用法

在Python的urllib库中,所有和网络请求相关的方法都集中到了urllib.request模块内。其中,urllib.request模块内的urlopen()函数用于实现对目标URL的访问。

urlopen()函数语法如下:


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

相关参数如下所示。

·url参数:目标资源在网络中的位置,可以是一个表示URL的字符串(如https://www.boxuegu.com/),也可以是一个urllib.request对象。

·data参数:用来指明发往服务器请求中的额外参数信息(如在线翻译、在线答题等提交的内容),data默认是None,此时以GET方式发送请求;当用户给出data参数的时候,改为以POST方式发送请求。

·cafile、capath、cadefault参数:用于实现可信任的CA证书的HTTP请求。

·context参数:实现SSL加密传输。

urlopen()返回一个类文件对象(fd),它提供了如下方法:read()、readline()、readlines()、fileno()以及close()。这些方法的使用方式与文件对象完全一样。info()返回一个httplib.HTTPMessage对象,表示远程服务器返回的头信息(header);getcode()返回http状态码,200表示请求成功完成;404表示网址未找到;geturl()返回请求的url。

关于urlopen()函数的使用方法,请参考例3-1和例3-2。

【例3-1】打开一个网页进行请求并获取所有内容


import urllib.request
response = urllib.request.urlopen('http://www.baidu.com')
print(response.read().decode('utf-8'))

部分结果如下所示:


<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <meta content="always" name="referrer">
    <meta name="theme-color" content="# 2932e1">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
    <link rel="search" type="application/opensearchdescription+xml" href="/content-search.xml" title="百度搜索" />
    <link rel="icon" sizes="any" mask href="//www.baidu.com/img/baidu_85beaf5496f291521eb75ba38eacbd87.svg">

【例3-2】利用type()方法查看返回的输出类型


import urllib.request
response = urllib.request.urlopen('http://www.baidu.com')
print(type(response))

输出结果如下:


<class 'http.client.HTTPResponse'>

这里能够知道返回的结果是一个HTTPResponse类型的对象。它主要包含read()、readinto()、getheader(name)、getheaders()、fileno()等方法,以及msg、version、status、reason、debuglevel、closed等属性。

在得到这个对象之后,我们能够将其赋予response变量,然后就可以调用这些方法和属性得到返回结果的一系列信息了。

例如,调用info()方法可以获取响应头信息,返回字符串;调用version属性可以获取HTTP协议版本号;调用status属性可以获取响应码,例如200为服务器已成功处理了请求,404为找不到请求的网页。

关于如何利用urlopen()和info()方法实现响应头信息的获取,可参考如下示例。

【例3-3】获取响应头信息


1  import urllib.request
2  response = urllib.request.urlopen('https://www.baidu.com')
3  print(response.status)
4  # 获取特定响应头信息
5  print(response.getheader(name="Content-Type"))
6  # 获取响应头信息,返回字符串
7  print(response.info())
8  # 获取HTTP协议版本号(HTTP1.0版本或HTTP1.1版本)
9  print(response.version)

运行结果如下所示:


200
text/html
Accept-Ranges: bytes
Cache-Control: no-cache
Content-Length: 227
Content-Type: text/html
Date: Mon, 27 May 2019 02:10:24 GMT
Etag: "5ce4c43c-e3"
Last-Modified: Wed, 22 May 2019 03:38:36 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Pragma: no-cache
Server: BWS/1.1
Set-Cookie: BD_NOT_HTTPS=1; path=/; Max-Age=300
Set-Cookie: BIDUPSID=69161032BED954853F4643F7AAAB402D; expires=Thu, 31-
Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1558923024; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2
147483647; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=0
X-Ua-Compatible: IE=Edge,chrome=1
Connection: close)

利用urlopen()就能实现最基本的、简单网页的GET请求抓取。在前面所展示的urlopen()函数语法中,除了url参数外还包含其他参数,例如data参数、timeout超时参数等。这里举一个data参数的例子。

【例3-4】data参数实例


1  import urllib.parse
2  import urllib.request
3  data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8')
4  response = urllib.request.urlopen('http://httpbin.org/post', data=data)
5  print(response.read()))

data参数是可供选择的,使用data参数时,若其是字节流编码格式的内容,即bytes类型,则需要通过bytes()函数进行转化。如果我们传递了这个data参数,那么它的请求方式就不再是GET方式请求,而是POST方式。

这里通过httpbin网页进行HTTP请求测试,其中包含我们传递的data参数。输出结果如下所示:


"args": {},
"data": "",
"files": {},
"form": {
         "word": "Python"
     },
"headers": {
         "Accept-Encoding": "identity",
         "Content-Length": "11",
         "Content-Type": "application/x-www-form-urlencoded",
         "Host": "httpbin.org",
         "User-Agent": "Python-urllib/3.6"
     },
     "json": null,
     "origin": "113.9.216.26, 113.9.216.26",
     "url": "http://httpbin.org/post"
}