初识urllib
使用urllib
request: 是最基本的 HTTP 请求模块,可以用来模拟发送请求,只需要给库方法传入URL以及额外的参数,就可以模拟实现这个过程了。
error: 异常处理模块,如果出现请求错误, 可以捕获这些异常,然后进行重试或其它操作以保证程序不会意外终止。
parse: 工具模块,提供了许多 URL 处理方法,比如拆分、解析,合并等。
robotparser: 主要是用来识别网站的robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬,用得较少。
发送请求
使用urllib的request模块,可以实现请求的发送并得到响应
具体用法:
urlopen()
urllib.request 模块提供了最基本的构造 HTTP请求的方法, 利用它可以模拟浏览器的一个请求发起过程, 同时它还带有处理授权验证( authenticaton )、重定向( redirection 、浏览器 Cookies 及其他内容
以百度为例,把网页抓下来
#!/usr/bin/env python
# coding: utf-8
import urllib.request
response = urllib.request.urlopen("http://www.baidu.com")
print(response.read().decode('utf8'))
运行结果如下:
这里只用了两行代码,便完成了百度首页的抓取,显示了网页的源代码,得到了源代码之后呢?想要的链接,图片地址,文本信息就可以从中提取出来。
利用type()函数查看response的数据类型
import urllib.request
response = urllib.request.urlopen("http://www.baidu.com")
print(type(response))
输出结果如下:
<class 'http.client.HTTPResponse'>
它是一个HTTPResponse类型的对象,主要包含read(),readinto(),getheader(name),getheaders(name),fileno()等方法以及msg,version,status,reason,debuglevel,closed等属性
调用read()方法可以得到返回的网页内容,调用status属性可以得到返回结果的状态码,如200代表请求成功,404代表网页未找到等。
实例如下:
#!/usr/bin/env python
# coding: utf-8
import urllib.request
response = urllib.request.urlopen("http://www.baidu.com")
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))
运行结果如下:
利用最基本的urlopen()方法,可以完成最基本的简单网页GET请求抓取。还可以传递一些参数,源码如下:
除了第一个参数可以传递URL之外,还可以传递其它内容,data(附加数据),timeout(超时时间)等....
参数详情介绍
data参数
data 参数是可选的。如果要添加该参数,并且如果它是字节流编码格式的内容,即 bytes 类型,则需要通过 bytes()方法转化。另外,如果传递了这个参数,则它的请求方式就不再是 GET 方式,而是POST方式.
实例:
#!/usr/bin/env python
# coding: utf-8
import urllib.request
import urllib.parse
data = bytes(urllib.parse.urlencode({'test': 'hello world'}), encoding='utf8')
response = urllib.request.urlopen("http://httpbin.org/post", data=data)
print(response.read().decode('utf8'))
运行结果如下
注释:上面传递了一个字典,键为test,值为hello wrod,传递过程中需要被转码为bytes(字节流)类型,类型转换用到了bytes()方法,该方法的第一个参数需是str(字符串)类型,而上面传的是一个字典类型,这个时候需要用urllib.parse模块里的urlencode()方法将字典转化成字符串;第二个参数指定编码格式为utf8。
http://httpbin.org/post,这个链接可以用来测试POST请求,传递的参数出现在form字段中,表示模拟了表单提交的方式,以POST方式传递数据。
timeout参数
timeout参数用于设置超时时间,单位为秒,意思就是超过设定的时间,还没有得到响应,就会抛出异常,不指定,使用全局默认时间,支持http,https,ftp请求。
实例:
#!/usr/bin/env python
# coding: utf-8
import urllib.request
response = urllib.request.urlopen("http://httpbin.org/get", timeout=1)
print(response.read().decode('utf8'))
运行结果如下:
注释:这里设置超时时间为1秒,1秒后没有响应,就会抛出异常,异常属于urllib.error模块
因此,可以通过设置这个超时时间来控制一个网页如果长时间未响应,就跳过它抓取,可以利用try except语句来实现,代码如下:
#!/usr/bin/env python
# coding: utf-8
import urllib.request
import urllib.error
import socket
try:
response = urllib.request.urlopen("http://httpbin.org/get", timeout=0.1)
except urllib.error.URLError as e:
if isinstance(e.reason, socket.timeout):
print("Time out")
运行结果如下:
Time out
注释:这里请求了http://httpbin.org/post测试连接,设置了超时时间为0.1秒,然后捕获了URLError异常,接着判断异常是socket.timeout类型(超时异常),得出确实是超时报错,最后打印Time out, 按照常理0.1秒内不可能得到服务器响应,所有超时,通过设置timeout这个参数来实现超时处理,还是很有用的
其它参数
除了 data 参数和 timeout 参数外,还有 context 参数,它必须是 ssl.SSLContext 类型,用来指定SSL设置, 此外,cafile和capath 这两个参数分别指定 CA 证书和它的路径,这个在请求 HTTPS 链接时会有用,若需要更加详细的文档信息,可以找到python的安装目录,找到Doc目录,下面会有一个pythons354.chrm文档,如下:
Request
利用urlopen()方法可以实现最基本请求的发起,但这个几个简单的参数并不足以构建一个完整的请求,如果请求中需要加入Headers等信息,就可以利用更强大的Request类来构建
Request用法实例:
#!/usr/bin/env python
# coding: utf-8
import urllib.request
request = urllib.request.Request('http://www.baidu.com')
response = urllib.request.urlopen(request)
print(response.read().decode('utf8'))
注释:依旧是用urlopen()方法来发送这个请求,不过这次该方法的参数不再是URL,而是一个Request类型的对象。通过构造这个数据结构,一方面我们可以将请求独立成一个对象,另一方面可更加丰富和灵活地配置参数。
Request构造源码如下:
第一个参数url用于请求URL,这是比传参数,其它都是可选
第二个参数data,如果需要传,必须传bytes(字节流)类型的。如果是字典,先用urllib.parse模块里的urlencode()编码
第三个参数 headers 是一个字典,它就是请求头, 在构造请求时通过 headers 参数直接构造,也可以通过调用请求实例的 add_header()方法添加。添加请求头最常用的用法就是通过修改 User-Agent 来伪装浏览器,默认的 User-Agent是Python-urllib,可以通过修改它来伪装成浏览器。
第四个参数 origin_req_host 指的是请求方的 host 名称或者 IP 地址。
第五个参数unverifiable 表示这个请求是否是无法验证的,默认是 False ,意思就是说用户没有足够权限来选择接收这个请求的结果。例如,请求一个HTML 文档中的图片,但是没有自动抓取图像的权限,这时 unverifiable 的值就是 True。
第六个参数method是一个字符串 ,用来指示请求使用的方法,比如 GET, POST, PUT等
实例,传入多个参数构建请求:
#!/usr/bin/env python
# coding: utf-8
from urllib import request,parse
url = 'http://httpbin.org/post'
headers = {
'User-Agent': 'Mozilla/4.0 (compatible; MSIE S. S; Windows NT)',
'Host': 'httpbin.org',
}
dict = {
'name': 'zhangsan'
}
data = bytes(parse.urlencode(dict), encoding='utf8')
req = request.Request(url=url, data=data, headers=headers, method='POST')
response = request.urlopen(req)
print(response.read().decode('utf8'))
运行结果如下;
注释:通过4个参数构造了一个请求,其中url即请求URL,headers中指定了User-Agent和Host,参数data用urloncode()和bytes()方法转成字节流,还指定了请求的方式为POST
通过上面的结果可以看出,成功设置了data,headers和method,另外headers也可以用add_header()方法来添加
req = request.Request(url=url, data=data, method='POST')
req .add_header('User-Agent', 'Mozilla/4 .0 (compatible; MSIE 5.5; Windows NT )')
这样更加方便地构造请求,实现请求的转发
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341