这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」
不得不说,这书真厚啊,不知道过年这几天我能看到哪里,最近工作上可出点小问题,玩不明白
timeout参数
timeout参数用来设置超时时间,单位为秒,这个参数支持HTTP HTTPS FTP请求
import urllib.request
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
response = urllib.request.urlopen("https://www.httpbin.org/get",timeout=0.1)
运行结果:报错 TimeoutError: _ssl.c:980: The handshake operation timed out
我们的超时时间设置的太短了,,程序运行0.1秒后,服务器没有给出响应,所以出现错误 我们看到这点,就可以通过超时时间,实现当一个网页长时间未响应时,跳过对它的抓取,可以使用try catch来进行异常处理.
import socket
import urllib.request
import ssl
try:
ssl._create_default_https_context = ssl._create_unverified_context
response = urllib.request.urlopen("https://www.httpbin.org/get",timeout=0.1)
except urllib.error.URLError as e:
if isinstance(e.reason,socket.timeout):
print("Time Out")
其他参数
除了data参数和timeout参数,urlopen还有context参数,上下文,该参数必须是ssl.SSLContext类型,用来设置SSL的设置,还有cafile和capath 很明显这俩是证书文件和证书路径的缩写嘛,这两个请求在HTTPS链接时会有用
Request
利用urlopen 方法可以发起最基本的请求,但是那几个简单的参数并不能完整的构建请求,如果需要在请求中加入Headers信息,就需要更强大的Request类来构建请求了.
import urllib.request
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
request = urllib.request.Request("http://python.org")
response = urllib.request.urlopen(request)
print(response.read().decode("utf-8"))
这次我们依然是使用urlopen来发送请求,但是,这次的参数确实Request对象,,通过这个数据结构,一方面可以将请求独立成一个对象,而且可以更方便的灵活地配置参数. 我们可以点进去看看,他的构造方法
- url 必要的,请求的地址
- data 如果要传数据,必须传bytes类型的,如果数据是字典,那么可以先用
urllib.parse模块的urlencode方法进行编码 - headers 请求头,是一个字典,可以通过浏览器的,来伪装
- origin_req_host 请求的主机名或者IP地址
- unverifiable 表示无法验证 有没有权限来接受响应
- method 字符串 用来表示请求的方法 //post/get/put
例如:
from urllib import request, parse
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
url = "https://www.httpbin.org/post"
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36",
"Host" : "www.httpbin.org"
}
dict = {"name":"flynt"}
data = bytes(parse.urlencode(dict),encoding="utf-8")
req = request.Request(url=url,data=data,headers=headers,method="POST")
response = request.urlopen(req)
print(response.read().decode("utf-8"))
结果:
{
"args": {},
"data": "",
"files": {},
"form": {
"name": "flynt"
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "10",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "www.httpbin.org",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36",
"X-Amzn-Trace-Id": "Root=1-61f29a83-39ab4c14005fa821717a4628"
},
"json": null,
"origin": "103.144.149.196",
"url": "https://www.httpbin.org/post"
}