模块
urllib包含了四个模块:
request:这是最基本的HTTP请求模块,可以模拟请求的发送,。和浏览器输入网站按回车搜索一样。只需要给库方法传入URL以及额外的参数,就可以模拟实现发送请求的过程。
error:异常处理模块。如果出现请求异常,那么我们可以捕获这些异常,然后进行重试或其它操作以保证程序运行不会意外终止。
parse:一个工具模块。提供了很多URL的处理方法,例如拆分、解析、合并等。
robtparser:主要用来识别网站的robots.txt文件,判断那些·网站可以爬,那些不行,用得比较少。
发送请求
使用urllib的request模块,可以发送请求并得到响应。
urlopen
urllib.request模块提供最基本的构造HTTP请求的方法,利用这个模块可以模拟浏览器的请求发送过程,同时还具备处理授权验证(authentication)、重定向(redirection)、浏览器cookie以及一些其他功能。
下面时抓取python官网:
import urllib.request
response = urllib.request.urlopen('https://www.python.org')
print(response.read().decode('utf-8'))
运行结果:
可以使用type方法输出响应的类型
import urllib.request
response = urllib.request.urlopen('https://www.python.org')
print(type(response))
import urllib.request
response = urllib.request.urlopen('https://www.python.org')
#print(response.read().decode('utf-8'))
#返回响应类型
#print(type(response))
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))
status:可以得到响应结果的状态码(200代表请求成功,404代表网页未找到等);
getheaders():可以得到响应的头信息;
getheader():调用方法传入参数Server,获取响应头中的Server的值,是nginx,意思是服务器是用Nginx搭建的。
想要给链接传递一些参数,该怎样操作呢?先看一下urlopen方法的API;
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
下面结束一下urlopen方法中的几个参数的用法:
data参数
data参数是可选的。在添加该参数时,需要使用bytes方法将参数转化为字节流编码格式的内容,即bytes类型。若传递了这个参数,那么请求方式就不是get了而是post了。
实例:
# data参数用法
import urllib.request
import urllib.parse
data = bytes(urllib.parse.urlencode({'name': 'germey'}), encoding='utf-8')
response = urllib.request.urlopen('https://www.httpbin.org/post', data=data)
print(response.read().decode('utf-8'))
这里传递了一个参数name,值是germey,需要将它转化成bytes类型。转码时采用了bytes方法,第一个参数是str类型,因此采用urllib.parse模块里的urlencode方法将字典参数转化为字符串;第二个参数用于指定编码格式,这里指定为utf-8。
我请求的战点是www.httpbin.org,它可以提供HTTP请求测试。本次我们请求的url为https://www.httpbin.org/post,这个链接可以用来测试post请求,能够输出一些信息,其中就包含我们传递的data参数。
运行结果:
可以看到,传递的参数出现在了form字段中,这表明是模拟表单提交,以post方式传输数据。
timeout参数
timeout参数用来设置超时时间(秒),意思是请求超出了设置的时间,未得到响应,就会抛出异常。若不指定该参数,则会使用全局,默认时间。该参数支持HTTP、HTTPS、FTP请求。
import urllib.request
response = urllib.request.urlopen('https://www.httpbin.org/get', timeout=0.1)
print(response.read())
请求了https://www.httpbin.org/get这个测试链接,设置超时链接为0.1秒,按常理0.1秒几乎不可能得到服务器的响应,会超时异常,不相信的小伙伴可以尝试。
我们可以通过try except语句实现,网页长时间未响应,跳过对其的抓取:
import urllib.request
import urllib.parse
import socket
import urllib.error
try:
response = urllib.request.urlopen('https://www.httpbin.org/get', timeout=0.1)
#改名为e
except urllib.error.URLError as e:
if isinstance(e.reason, socket.timeout):
print('TIME OUT')
结果:
在这里捕获到了ERLError这个异常,并判断异常为socket.timeout,意思为超时异常,因此得到超时报错的结论,输出TIME OUT。
除以上参数外还有context参数,该参数必须是ssl.SSLContext类型,用来指定SSL的设置。 此外,cafile和capath两个参数分别用来指定C证书和其路径,这两个在请求HTTPS链接时会有用。
cadefault参数现在已经弃用,默认值为False。