中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

【從0開始Python開發實戰】掌握Python urllib,HTTP開發進階

發布時間:2020-05-19 05:50:23 來源:網絡 閱讀:593 作者:jextop 欄目:編程語言

目錄:

1.?urllib介紹

2.?功能開發http_util.py

3.?單元測試test_http_util.py,實際調用百度AI語音合成接口

4.?常見問題和解決方法


一,urllib介紹

Python在AI領域是主流開發語言,更多的軟件應用開發也開始使用Python,有非常多且好用的標準庫和第三方組件,urllib是Python自帶的標準庫,不需要安裝,用于HTTP開發,主要模塊和功能:

1.?urllib.request: 發送HTTP請求,接收處理HTTP響應

2.?urllib.error: 處理錯誤和異常,包含urllib.request拋出的異常

3.?urllib.parse: 解析URL和編碼數據

4.?urllib.robotparser: 解析robots.txt


本文介紹urllib庫中的request, error, parse三個模塊在HTTP開發時的代碼應用,并封裝成http_util,單元測試函數實際調用百度AI語音合成接口,和項目開發一致:

1,調用鑒權接口獲取token:https://openapi.baidu.com/oauth/2.0/token

2,調用語音合成接口轉換文本為語音:https://tsn.baidu.com/text2audio


開源項目:https://github.com/jextop/starter_service

示例代碼:https://github.com/rickding/HelloPython/tree/master/hello_http

├── util

│ ??└── http_util.py

│ ??└── file_util.py

│ ??└── code_util.py

├── tests

│ ??└── test_http_util.py


二,功能開發


代碼文件

功能要點

功能開發

http_util.py

調用urllib發送請求,接收和處理響應

單元測試

test_http_util.py

測試封裝的功能函數,調用百度AI鑒權接口獲取access_token,調用語音合成接口將文本轉換為語音

輔助功能

file_util.py

下載文件時,保存文件

code_util.py

保存文件時生成唯一名稱

1.?urllib.request.urlopen()可以直接調用url地址,得到響應,讀取數據,簡單HTTP請求使用起來非常方便:

from urllib import request

resp = request.urlopen(r'http://www.baidu.com')
data = resp.read()
data_str = data.decode('utf-8')
print(data_str)

2.?urllib.request.urlopen()支持Request類型參數,構造Request時配置更多的參數如header, data:

from urllib import parse
from urllib import request

req = request.Request(
????'https://tsn.baidu.com/text2audio',
????headers={
????????'Content-Type': 'application/x-www-form-urlencoded',
????},
????data=parse.urlencode({
????????'tex': 'Python開發HTTP請求和處理響應',
????}).encode('utf-8'),
????method='POST'
)
resp = request.urlopen(req)
data = resp.read()
data_str = data.decode('utf-8')
print(data_str)

3.?封裝http_data()函數,發起http請求和處理響應,注意encode()函數是對parse.urlencode()的調用封裝,將data轉換為byte數據:

import logging
from urllib import error
from urllib import parse
from urllib import request

log = logging.getLogger(__name__)

def http_data(url, headers={}, data=None, method=None):
????try:
????????req = request.Request(url, headers=headers, method=method, data=encode(data))
????????resp = request.urlopen(req)
????????data = resp.read()
????????log.info('http_data returns: %d, %s, %s' % (len(data), type(data), url))
????????return data
????except (ConnectionError, error.URLError) as e:
????????log.error('ConnectionError in http_data: %s, %s' % (url, str(e)))
????except Exception as e:
????????log.error('Exception in http_data: %s, %s' % (url, str(e)))

????return None

def encode(data):
????if isinstance(data, dict):
????????data = parse.urlencode(data)

????if isinstance(data, str):
????????data = data.encode('utf-8')

????return data

4.?封裝http_str(),將HTTP響應數據解析為字符串:

def http_str(url, headers={}, data=None, method=None):
????data = http_data(url, headers, data, method)
????return None if data is None else data.decode('utf-8')

5.?封裝http_json(),在響應數據為JSON內容時,解析為dict:

def http_json(url, headers={}, data=None, method=None):
????data = http_data(url, headers, data, method)
????return None if data is None else json.loads(data)

6.?封裝http_file(),下載文件時,返回數據為二進制文件內容,存儲到服務器或客戶端,代碼詳見http_util.http_file()函數,執行流程:

a)?拼裝請求參數,得到響應,調用resp.read()讀取二進制數據文件內容

b)?讀取頭信息Content-Disposition,是否返回了文件名稱?比如:attachment;fileName=zip.zip

c)?讀取頭信息Content-Type,解析文件格式,比如:audio/wav

d)?將文件數據保存


三,單元測試test_http_util.py

調用http_util封裝的功能函數,測試如下:

1.?test_http_str()請求http://www.baidu.com,得到字符串信息:

class HttpUtilTest(TestCase):
????def test_http_str(self):
????????ret_str = http_str('http://www.baidu.com')
????????log.info('http_str returns: %s' % ret_str[0: 20])
????????self.assertIsNotNone(ret_str)

2.?Test_http_json()調用百度鑒權接口庫,返回JSON格式數據,解析得到access_token

class HttpUtilTest(TestCase):
????def test_http_json(self):
????????ret_json = http_json('https://openapi.baidu.com/oauth/2.0/token', headers={
????????????'Content-Type': 'application/x-www-form-urlencoded',
????????}, data={
????????????'grant_type': 'client_credentials',
????????????'client_id': 'kVcnfD9iW2XVZSMaLMrtLYIz',
????????????'client_secret': 'O9o1O213UgG5LFn0bDGNtoRN3VWl2du6',
????????}, method='POST')

????????log.info('http_json returns: %s' % ret_json)
????????self.assertIsNotNone(ret_json)

????????token = ret_json.get('access_token')
????????print(token)

3.?call_http_file()調用百度AI語音合成接口,得到文本轉換成的語音數據,保存為文件:

class HttpUtilTest(TestCase):
????def call_http_file(self, token):
????????[ret, file_name, data] = http_file('https://tsn.baidu.com/text2audio', headers={
????????????'Content-Type': 'application/x-www-form-urlencoded',
????????}, data={
????????????'tex': 'Python開發異步任務調度和業務處理',
????????????'tok': token,
????????????'cuid': 'starter_service_http_util',
????????????'ctp': '1',
????????????'lan': 'zh',
????????????'spd': '6',
????????????'per': '1',
????????}, method='POST', save_to_disc=True, save_as_temp=False)

????????log.info('http_file returns: %s, %s, %s' % (ret, str(file_name), type(data)))
????????self.assertIsNotNone(ret is False or len(data) > 0)

4.?運行python manage.py test,得到語音文件<項目路徑>/tmp/http_download/xxx.mp3:

【從0開始Python開發實戰】掌握Python urllib,HTTP開發進階

【從0開始Python開發實戰】掌握Python urllib,HTTP開發進階

四,常見問題和解決方法

l?下載文件時,如果獲取文件名稱和類型?

解決:HTTP響應返回的頭信息中含有文件名稱和類型,但是注意這些信息可能沒有返回,代碼中要判斷信息不存在的情況:

- 頭信息Content-Disposition,包含文件名稱比如:attachment;fileName=zip.zip

- 頭信息Content-Type,包含文件格式,比如:audio/wav

# parse file type, e.g. audio/wav
file_type = None
content_type = resp.getheader('Content-Type')
if '/' in str(content_type):
????file_type = content_type.split('/')[1]

# parse file name, e.g. attachment;fileName=zip.zip
file_name = None
disposition = resp.getheader('Content-Disposition')
if '=' in str(disposition):
????file_name = disposition.split('=')[1]

# use a new file name
if file_name is None:
????file_name = '%s.%s' % (get_code(), file_type or 'dat')


l?調用請求傳遞參數時出錯:

POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.

另一個同類錯誤:

can't concat str to bytes


解決:調用urllib.parse.urlencode()將數據編碼,或者調用封裝的http_util.encode()

原因:urllib.request.Request()的data參數類型要求byte

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

柯坪县| 江川县| 平和县| 丰原市| 元氏县| 河间市| 行唐县| 榆中县| 枞阳县| 静安区| 综艺| 富源县| 修水县| 饶阳县| 江津市| 庆安县| 彰化县| 栾川县| 治多县| 南平市| 大新县| 玛沁县| 偏关县| 建德市| 乳山市| 阳朔县| 杂多县| 吴旗县| 万山特区| 迁西县| 芦山县| 得荣县| 稻城县| 上林县| 邹平县| 万全县| 育儿| 郑州市| 全椒县| 平乡县| 理塘县|