Win8.1-32位,python3.4为www.douban.com制作了一个网络机器人来获取主要的html,jpg和png文件。但完成后,我无法打开图片文件。(Windows照片查看器无法打开此图片balablabala)
问题:
1:为什么图片打不开?
2:如果像this:dbr.write(data)一样编辑第35行,命令行将提示: TypeError:'str‘不支持缓冲区接口。同样的事情也会发生在51和59行。但是,当第35行是字节(:dbr.write(data,'UTF-8'))时,我将获得正确的html文件。所以我对图片文件的51行和59行做了同样的处理,但有些地方出了问题。我想知道"write()“中应该有一个bug,但是我不知道到底是哪里出了问题。
下面是代码。
import urllib.request
import os
import re
#make dirs for douban_robot, jpg, png
dirpath = 'D:/Pwork/webrobot/'
if not os.path.isdir(dirpath):
os.makedirs(dirpath)
jpg_path = dirpath + 'jpgfiles/'
png_path = dirpath + 'pngfiles/'
if not os.path.isdir(jpg_path):
os.makedirs(jpg_path)
if not os.path.isdir(png_path):
os.makedirs(png_path)
douban_robot = dirpath + 'douban.html'
url = 'http://www.douban.com'
#get .html
data = urllib.request.urlopen(url).read().decode('UTF-8')
with open(douban_robot, 'wb') as dbr:
dbr.write(bytes(data, 'UTF-8'))
dbr.close()
# create regex
re_jpg = re.compile(r'<img src="(http.+?.jpg)"')
re_png = re.compile(r'<img src="(http:.+?.png)"')
jpg_data = re_jpg.findall(data)
png_data = re_png.findall(data)
# for test jpg and png date
print(jpg_data, png_data)
#get jpg files
i = 1
for image in jpg_data:
jpg_name = jpg_path + str(i)+'.jpg'
#urllib.request.urlretrieve(image, jpg_name)
with open(jpg_name, 'wb') as jpg_file:
jpg_file.write(bytes(image, 'UTF-8'))
jpg_file.close()
i += 1
for image in png_data:
png_name = png_path + str(i)+'.png'
#urllib.request.urlretrieve(image, png_name)
with open(png_name, 'wb') as png_file:
png_file.write(bytes(image, 'UTF-8'))
png_file.close()
i += 1发布于 2015-07-17 23:44:47
jpg_data和png_data是包含捕获的URL的列表。循环遍历每个URL,将URL字符串放在变量image中。然后,在两个循环中,将URL字符串写入文件,而不是实际的图像。实际上,看起来注释掉的urllib行可以完成任务,而不是你现在正在做的事情。.write()函数希望你给它一个匹配文件模式的对象。当您调用open(..., 'wb')时,您要求以write和binary模式打开文件,这意味着您需要为其提供bytes而不是binary字节是所有东西存储在计算机中的基本方式。一切都是由一系列字节组成的--硬盘上的数据,以及您在Internet上发送和接收的数据。字节本身并没有真正的意义--每个字节只有8位串在一起。其含义取决于您如何解释字节。例如,您可以将单个字节解释为表示从0到255的数字。或者,您可以将其解释为-128到127之间的数字(这两个数字都很常见)。您还可以将这些“数字”分配给字符,并将一个字节序列解释为文本。然而,这只允许您表示256个字符,而且在世界上的各种语言中还有更多的字符。因此,有多种方法可以将文本表示为字节序列。这些被称为“字符编码”。最流行的现代格式是"UTF-8“。
在Python语言中,bytes对象只是一系列字节。它没有特殊的含义--还没有人说出它代表了什么。如果您希望将其用作文本,则需要使用其中一种字符编码对其进行解码。一旦你这样做了(.decode('UTF-8')),你就有了一个str对象。为了将其写入磁盘(或网络),您的str最终必须被编码回字节。当你在文本模式下打开一个文件时,Python会选择你计算机的默认编码,它会解码你用它读取的所有内容,并对你写的所有内容进行编码。但是,当您在b模式下打开一个文件时,Python期望您给它一个bytes,所以当您给它一个str时,它会抛出一个错误。既然您知道下载并放入data中的HTML文件是文本,那么最好将其保存为文本模式的文件。但是,只要系统的默认编码为UTF-8,将其编码为UTF-8并将其写入二进制文件也是可行的。通常,当你有一个模式并且你想把它写到一个文件中时,以文本模式打开文件(只是不要在str参数中传递b ),让Python选择编码,因为Python比你更清楚!
有关字符集和编码的更多信息(我只是略过),您真的应该阅读this文章。
https://stackoverflow.com/questions/31479065
复制相似问题