1.发送请求
利用urllib.request模块提供了最基本的构造HTTP请求的方法,利用这个模块可以模拟浏览器的请求发起过程。
首先以python官网为例,抓取这个网页
import urllib.request
response = urllib.request.urlopen('https://www.python.org')
print(response.read().decode('utf-8'))
运行结果如下图所示.
由此可见,利用urlopen方法可以发起最基本的请求,但不足以构建成一个完整的请求,所以需要往请求中加入Headers等信息,就得利用更强大的Request类来构建请求了。
import urllib.request
url = 'https://www.python.org'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.7062 SLBChan/105'
}
request = urllib.request.Request(url=url,header=header)
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))
以上就是urllib库的基本使用。
2.get请求参数问题
这里就得使用到urllib里面的另一个模块parse,先需要了解parse模块中quote和unquote方法
quote:该方法可以将内容转化为URL编码的格式。可将中文字符转化为URL编码
unquote:该方法与quote相反
实例如下:
import urllib.request
import urllib.parse
name = input('请输入你想要查询的名字:')
name_url = quote(name)
print(name_url)
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.7062 SLBChan/105'
}
start_url = 'https://www.baidu.com/s?wd='
url = start_url + name_url
request = urllib.request.Request(url = url,headers=headers)
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))
3.get请求多参数
这里使用parse模块中的urlencode方法,首先得声明一个字典params,用于将参数表示出来,然后调用urlencode方法将params序列化为GET请求的参数。
import urllib.request
import urllib.parse
params = {
'name':'周杰伦',
'age':'18'
}
code = urllib.parse.urlencode(params)
print(code)
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.7062 SLBChan/105',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
}
start_url = 'https://www.baidu.com/s?wd='
url = start_url + code
request = urllib.request.Request(url=url,headers=headers)
response = urllib.resquest.urlopen(request)
print(response.read().decode('utf-8'))
4.post请求参数
这里需要导入一个json库来转化为json数据类型,通过百度翻译案例来分析,打开f12,然后在百度翻译输入你想要翻译的值,在network里拿到sug看到的是post请求。
import urllib.request
import urllib.parse
import json
data = {
'kw':'spider'
}
url = 'https://fanyi.baidu.com/sug'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.7062 SLBChan/105'
}
code = urllib.parse.urlopen(data).encode('utf-8')
request = urllib.request.Request(url=url,headers=headers,data=code)
response = urllib.request.urlopen(request)
content = resposne.read().decode('utf-8')
obj = json.load(content)
print(obj)
运行结果如下图
5.异常处理模块
我们已经了解到如何发送完整的请求以及怎么应对get和post请求,但是在网络不好的情况下,如果出现了异常,程序就会因为报错而终止运行,所以异常处理是非常有必要的。
这里使用的是error模块中的URLError来抛出异常(由request的模块产生的异常都能捕获到)
from urllib import request,error
try:
response = request.urlopen('https://cuiqingcai.com/404')
except error.URLError as e:
print(e.reason)
我们打开了一个不存在的页面,照理说会报错,这里我们捕获到了error的异常结果如下:
Not Found
HTTPError是URLError的子类,专门用来处理HTTP请求错误
from urllib import request,error
try:
response=request.urlopen('https://cuiqingcai.com/404')
except error.HTTPError as e:
print(e.reason,e.code,e.headers,sep='\n')
依然是打开同样的网址,这里捕获到了HTTPError的异常,输出了reason、code和headers等属性
因为URLError是HTTPError的父类,所以可以先选择捕获子类的错误,再捕获父类的错误
from urllib import request,error
try:
response = request.urlopen('https://cuiqingcai.com/404')
except error.HTTPError as e:
print(e.reason,e.code,e.headers,sep='\n')
except error.URLError as e:
print(e.reason)
else:
print('Request Successfully')
6.Robot协议
这里使用robotparser模块来解析robots.txt文件
from urllib.robotparser import RobotFileParser
rp = RobotFileParser()
rp.set_url('https://www.baidu.com/robots.txt')
rp.read()
print(rp.can_fetch('Baiduspider','https://www.baidu.com'))
print(rp.can_fetch('Baiduspider','https://www.baidu.com/homepage/'))
print(rp.can_fetch('Goodlebot','https://www.baidu.com/homepage'))
结果如下
利用此模块,我们可以方便的判断哪些页面可以抓取,哪些页面不能。
总结:这篇主要介绍了urllib库的request、error、parse、robotparser模块的基本用法,这些是一些基本模块,有一些模块的使用性还是很强的。