PyQt 教程中的 QNetworkAccessManager 展示了如何显示如何使用QNetworkAccessManager
发送请求和接收响应。
QNetworkAccessManager
QNetworkAccessManager
允许应用发送网络请求和接收回复。 QNetworkRequest
保留要与网络管理器发送的请求,QNetworkReply
包含返回的数据和响应头。
QNetworkAccessManager
具有异步 API,这意味着其方法总是立即返回,并且不等到完成时才返回。 而是在请求完成时发出信号。 我们通过附加到完成信号的方法来处理响应。
HTTP GET 请求
HTTP GET 方法请求指定资源的表示形式。
get_request.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
'''
QNetworkAccessManager in PyQt
In this example we get a web page.
Author: Jan Bodnar
Website: zetcode.com
Last edited: September 2017
'''
from PyQt5 import QtNetwork
from PyQt5.QtCore import QCoreApplication, QUrl
import sys
class Example:
def __init__(self):
self.doRequest()
def doRequest(self):
url = "http://www.something.com"
req = QtNetwork.QNetworkRequest(QUrl(url))
self.nam = QtNetwork.QNetworkAccessManager()
self.nam.finished.connect(self.handleResponse)
self.nam.get(req)
def handleResponse(self, reply):
er = reply.error()
if er == QtNetwork.QNetworkReply.NoError:
bytes_string = reply.readAll()
print(str(bytes_string, 'utf-8'))
else:
print("Error occured: ", er)
print(reply.errorString())
QCoreApplication.quit()
app = QCoreApplication([])
ex = Example()
sys.exit(app.exec_())
该示例检索指定网页的 HTML 代码。
url = "http://www.something.com"
req = QtNetwork.QNetworkRequest(QUrl(url))
使用QNetworkRequest
,我们将请求发送到指定的 URL。
self.nam = QtNetwork.QNetworkAccessManager()
self.nam.finished.connect(self.handleResponse)
self.nam.get(req)
创建一个QNetworkAccessManager
对象。 请求完成后,将调用handleResponse()
方法。 使用get()
方法触发该请求。
def handleResponse(self, reply):
er = reply.error()
if er == QtNetwork.QNetworkReply.NoError:
bytes_string = reply.readAll()
print(str(bytes_string, 'utf-8'))
else:
print("Error occured: ", er)
print(reply.errorString())
QCoreApplication.quit()
handleResponse()
接收QNetworkReply
对象。 它包含已发送请求的数据和标头。 如果网络回复中没有错误,我们将使用readAll()
方法读取所有数据; 否则,我们将显示错误消息。 errorString()
返回人类可读的最后发生的错误的描述。 readAll()
返回QByteArray
中必须解码的数据。
$ ./get_request.py
<html><head><title>Something.</title></head>
<body>Something.</body>
</html>
这是输出。
HTTP POST 请求
HTTP POST 方法将数据发送到服务器。 请求正文的类型由Content-Type
标头指示。 POST 请求通常通过 HTML 表单发送。 请求中发送的数据可以采用不同的方式进行编码。 在application/x-www-form-urlencoded
中,值被编码为以’&’分隔的键值元组,键和值之间带有’=’。 非字母数字字符采用百分比编码。 multipart/form-data
用于二进制数据和文件上传。
post_request.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
'''
QNetworkAccessManager in PyQt
In this example we post data to a web page.
Author: Jan Bodnar
Website: zetcode.com
Last edited: September 2017
'''
from PyQt5 import QtCore, QtGui, QtNetwork
import sys, json
class Example:
def __init__(self):
self.doRequest()
def doRequest(self):
data = QtCore.QByteArray()
data.append("name=Peter&")
data.append("age=34")
url = "https://httpbin.org/post"
req = QtNetwork.QNetworkRequest(QtCore.QUrl(url))
req.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader,
"application/x-www-form-urlencoded")
self.nam = QtNetwork.QNetworkAccessManager()
self.nam.finished.connect(self.handleResponse)
self.nam.post(req, data)
def handleResponse(self, reply):
er = reply.error()
if er == QtNetwork.QNetworkReply.NoError:
bytes_string = reply.readAll()
json_ar = json.loads(str(bytes_string, 'utf-8'))
data = json_ar['form']
print('Name: {0}'.format(data['name']))
print('Age: {0}'.format(data['age']))
print()
else:
print("Error occurred: ", er)
print(reply.errorString())
QtCore.QCoreApplication.quit()
app = QtCore.QCoreApplication([])
ex = Example()
sys.exit(app.exec_())
该示例将发布请求发送到https://httpbin.org/post
测试站点,该站点将数据以 JSON 格式发送回。
data = QtCore.QByteArray()
data.append("name=Peter&")
data.append("age=34")
根据规范,我们对QByteArray
中发送的数据进行编码。
url = "https://httpbin.org/post"
req = QtNetwork.QNetworkRequest(QtCore.QUrl(url))
req.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader,
"application/x-www-form-urlencoded")
我们指定application/x-www-form-urlencoded
编码类型。
bytes_string = reply.readAll()
json_ar = json.loads(str(bytes_string, 'utf-8'))
data = json_ar['form']
print('Name: {0}'.format(data['name']))
print('Age: {0}'.format(data['age']))
print()
在处理程序方法中,我们读取响应数据并将其解码。 使用内置的json
模块,我们提取发布的数据。
$ ./post_request.py
Name: Peter
Age: 34
这是输出。
使用QNetworkAccessManager
进行身份验证
每当最终服务器在传递所请求的内容之前请求认证时,都会发出authenticationRequired
信号。
authenticate.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
'''
QNetworkAccessManager in PyQt
In this example, we show how to authenticate
to a web page.
Author: Jan Bodnar
Website: zetcode.com
Last edited: September 2017
'''
from PyQt5 import QtCore, QtGui, QtNetwork
import sys, json
class Example:
def __init__(self):
self.doRequest()
def doRequest(self):
self.auth = 0
url = "https://httpbin.org/basic-auth/user7/passwd7"
req = QtNetwork.QNetworkRequest(QtCore.QUrl(url))
self.nam = QtNetwork.QNetworkAccessManager()
self.nam.authenticationRequired.connect(self.authenticate)
self.nam.finished.connect(self.handleResponse)
self.nam.get(req)
def authenticate(self, reply, auth):
print("Authenticating")
self.auth += 1
if self.auth >= 3:
reply.abort()
auth.setUser("user7")
auth.setPassword("passwd7")
def handleResponse(self, reply):
er = reply.error()
if er == QtNetwork.QNetworkReply.NoError:
bytes_string = reply.readAll()
data = json.loads(str(bytes_string, 'utf-8'))
print('Authenticated: {0}'.format(data['authenticated']))
print('User: {0}'.format(data['user']))
print()
else:
print("Error occurred: ", er)
print(reply.errorString())
QtCore.QCoreApplication.quit()
app = QtCore.QCoreApplication([])
ex = Example()
sys.exit(app.exec_())
在示例中,使用https://httpbin.org
网站显示如何使用QNetworkAccessManager
进行身份验证。
self.nam.authenticationRequired.connect(self.authenticate)
我们将authenticationRequired
信号连接到authenticate()
方法。
def authenticate(self, reply, auth):
print("Authenticating")
...
authenticate()
方法的第三个参数是QAuthenticator
,用于传递所需的身份验证信息。
self.auth += 1
if self.auth >= 3:
reply.abort()
如果验证失败,则QNetworkAccessManager
会继续发出authenticationRequired
信号。 在三次失败的尝试之后,我们中止了该过程。
auth.setUser("user7")
auth.setPassword("passwd7")
我们将用户和密码设置为QAuthenticator
。
bytes_string = reply.readAll()
data = json.loads(str(bytes_string, 'utf-8'))
print('Authenticated: {0}'.format(data['authenticated']))
print('User: {0}'.format(data['user']))
print()
https://httpbin.org
用 JSON 数据响应,该数据包含用户名和指示认证成功的布尔值。
$ ./authenticate.py
Authenticating
Authenticated: True
User: user7
这是输出。
提取一个网站图标
网站图标是与特定网站相关的小图标。 在以下示例中,我们将从网站上下载网站图标。
fetch_icon.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
'''
QNetworkAccessManager in PyQt
In this example we fetch a favicon from
a website.
Author: Jan Bodnar
Website: zetcode.com
Last edited: September 2017
'''
from PyQt5 import QtCore, QtGui, QtNetwork
import sys
class Example:
def __init__(self):
self.doRequest()
def doRequest(self):
url = "http://www.google.com/favicon.ico"
req = QtNetwork.QNetworkRequest(QtCore.QUrl(url))
self.nam = QtNetwork.QNetworkAccessManager()
self.nam.finished.connect(self.handleResponse)
self.nam.get(req)
def handleResponse(self, reply):
er = reply.error()
if er == QtNetwork.QNetworkReply.NoError:
data = reply.readAll()
self.saveFile(data)
else:
print("Error occured: ", er)
print(reply.errorString())
QtCore.QCoreApplication.quit()
def saveFile(self, data):
f = open('favicon.ico', 'wb')
with f:
f.write(data)
app = QtCore.QCoreApplication([])
ex = Example()
sys.exit(app.exec_())
该代码示例下载了 Google 的收藏夹图标。
self.nam.get(req)
我们使用get()
方法下载图标。
data = reply.readAll()
self.saveFile(data)
在handleResponse()
方法中,我们读取数据并将其保存到文件中。
def saveFile(self, data):
f = open('favicon.ico', 'wb')
with f:
f.write(data)
图像数据以saveFile()
方法保存在磁盘上。
在本教程中,我们使用了QNetworkAccessManager
。
您可能也对以下相关教程感兴趣: QPropertyAnimation 教程,QNetworkAccessManager 教程。