鍍金池/ 問答/數(shù)據(jù)分析&挖掘  Java  Python  C++  網(wǎng)絡(luò)安全/ python urllib request urlopen請求網(wǎng)頁返回bytes

python urllib request urlopen請求網(wǎng)頁返回bytes類型

我在學(xué)習(xí)urllib這個庫,使用以下代碼請求面度的主頁,返回的結(jié)果為<class 'bytes'>,我嘗試了多種方法進(jìn)行解碼,均不成功(報錯或?yàn)榭眨?br>以下為代碼:

from urllib import request
f = request.urlopen('http://www.baidu.com/')
print(f.read())
print(type(f.read()))
x = f.read()
print(x.decode(encoding='utf-8'))

以下為輸出:
……n</body>n</html>nrnrnrnnrn'
<class 'bytes'>
''
請大佬指點(diǎn),謝謝!
圖片描述

回答
編輯回答
傻丟丟

不建議使用 urllib 庫,推薦 requests 庫

import requests
response = requests.get('https://www.baidu.com/')
response.encoding = 'utf-8'
print(response.text)
2018年7月2日 07:48
編輯回答
鹿惑

首次調(diào)用read()時有返回,之后的調(diào)用一直返回b''

>>> f = request.urlopen('http://www.baidu.com/')
>>> f.read()
b'<!DOCTYPE html>\n<!--STATUS OK-->\n\r...(略)...'
>>> f.read()
b''

因此,從你的第二個f.read()開始,都是返回b''了。
這樣代碼在我這能正確獲取網(wǎng)頁并解碼:

from urllib import request
f = request.urlopen('http://www.baidu.com/')
x = f.read()
print(x.decode(encoding='utf-8'))

http.client.HTTPResponse.read是這樣定義的:

def read(self, amt=None):
    if self.fp is None:
        return b""

    if self._method == "HEAD":
        self._close_conn()
        return b""

    if amt is not None:
        # Amount is given, implement using readinto
        b = bytearray(amt)
        n = self.readinto(b)
        return memoryview(b)[:n].tobytes()
    else:
        # Amount is not given (unbounded read) so we must check self.length
        # and self.chunked

        if self.chunked:
            return self._readall_chunked()
...(略)...

第一次read()時,在self._readall_chunked()self.fp被置為None,并關(guān)閉了self.fp。
因此再次調(diào)用read()時,直接返回了b''。

2017年8月9日 00:01