IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> urllib.request.urlopen(url)不能两次.read()? -> 正文阅读

[Python知识库]urllib.request.urlopen(url)不能两次.read()?

问题描述:

笔者在初学Python爬虫时,用到 urllib.request.urlopen 获取百度搜索页面 (http://www.baidu.com) 上的信息。

首先,访问百度并获取网页信息,将信息保存在 response 中。代码如下:

from urllib.request import urlopen
url = r'http://www.baidu.com'
response = urlopen(url)

然后,调用 .read() 看一下 response 的内容,发现 charset=utf-8,于是用 utf-8 解码。代码如下:

print(response.read())

''' 

结果:
b'<!DOCTYPE html><!--STATUS OK-->\n\n\n    
<html><head><meta http-equiv="Content-Type" content="text/html;
charset=utf-8">
......'

'''

最后,用 utf-8 解码 response 的内容,并把解码后的内容保存到 百度.html 中。代码如下:

with open(r'百度.html','w') as f:
    f.write(response.read().decode('utf-8'))

然而,打开 百度.html 后却发现其一片空白???

现在打印一下 response.read().decode(‘utf-8’),居然也是空的???

print(response.read().decode('utf-8'))
''' 结果:b'' '''

探索原因:

首先,检查一下 response.read() 的内容是从哪一步开始变为空的。代码如下:

from urllib.request import urlopen
url = r'http://www.baidu.com'
response = urlopen(url)
print('1','-'*100,'\n',response.read(),sep='')
print('2','-'*100,'\n',response.read(),sep='')
with open(r'百度.html','w') as f:
    print('3','-'*100,'\n',response.read(),sep='')
    f.write(response.read().decode('utf-8'))
print('4','-'*100,'\n',response.read(),sep='')

'''
结果:
1----------------------------------------------------------------------------------------------------
b'<!DOCTYPE html><!--STATUS OK-->\n\n\n    <html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8">......
2----------------------------------------------------------------------------------------------------
b''
3----------------------------------------------------------------------------------------------------
b''
4----------------------------------------------------------------------------------------------------
b''
'''

发现,在 response.read() 写入 百度.html 前, response.read() 就已经变为空的了,即 response 的第一次 .read() 一切顺利,但是第二次 .read() 就变为空的了。

于是,我们探索一下 response.read()。
通过查看帮助文档,发现response.read 只有一个参数 amt:当 amt=None/负数 时,会读取所有字节;当 amt=正数k 时,会读取 k 个字节。

from urllib.request import urlopen
url = r'http://www.baidu.com'
response = urlopen(url)
print('1','-'*100,'\n',response.read(amt=20),sep='')
print('2','-'*100,'\n',response.read(amt=40),sep='')
response = urlopen(url)
print('3','-'*100,'\n',response.read(amt=60),sep='')
'''
结果:
1----------------------------------------------------------------------------------------------------
b'<!DOCTYPE html><!--S'
2----------------------------------------------------------------------------------------------------
b'TATUS OK-->\n\n\n    <html><head><meta http'
3----------------------------------------------------------------------------------------------------
b'<!DOCTYPE html><!--STATUS OK-->\n\n\n    <html><head><meta http'
'''

可以看到,在第一步解读 response 的前 20 个字节后,第二步解读的 40 个字节,是指 response 的第 21-60 个字节,而非前 40 个。第三步重新获取 response ,并解读其前 60 个字节,刚好是 第一步 与 第二步 的拼接。

因此,response.read() 解读了 response 的所有字节,再次使用 response.read() 时才会得到空的结果。


解决方案:

确定解码类型时,可以先打开网页源码查看 charset=utf-8,然后直接将 response.read().decode(‘utf-8’) 写入 百度.html。代码如下:

from urllib.request import urlopen
url = r'http://www.baidu.com'
response = urlopen(url)
with open(r'百度.html','w') as f:
    f.write(response.read().decode('utf-8'))

如有不当之处,烦请指出!

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-02-05 21:41:53  更:2022-02-05 21:43:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 2:30:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码