环境:python3。
有许多文件,其中一些用gbk编码,另一些用utf-8编码。
我想用正则表达式提取所有jpg
使用gbk进行s.html编码。
tree = open("/tmp/s.html","r").read()
UnicodeDecodeError:'utf-8'编解码器无法解码位置135的字节0xb4:无效的起始字节
tree = open("/tmp/s.html","r",encoding="gbk").read()
pat = "http://.+\.jpg"
result = re.findall(pat,tree)
print(result)
[ 'http://somesite/2017/06/0_56.jpg']
使用指定的编码打开所有文件是一项巨大的工作,我想要一种智能的方法来提取所有文件中的jpg网址。
答案 0 :(得分:2)
我有类似的问题,我如何解决这个问题如下。
在get_file_encoding(filename)
中,我首先检查文件中是否有BOM(字节顺序标记),如果是,则从BOM中获取编码。从功能:get_file_bom_encodig(filename)
如果没有返回值,我会从函数中获取一个列表:get_all_file_encoding(filename)
这个列表将包含文件可以打开的所有编码。出于我的目的,我只需要一个,我不关心其余的,所以我只选择列表的第一个值{ {1}}
这显然不准确100%,但至少它会从BOM中为您提供正确的编码,或者它会为您提供可以打开文件的编码列表。或者,如果你这样做,它将给你一个(第一个值)编码文件可以打开而没有错误。
这里是代码:
file_encoding = str(encoding_list[0][0])
我确信有些模块/软件包可以更准确地完成这项工作,但这是通过标准软件包完成的(这是我的另一项要求)
这确实意味着您正在多次读取文件,这不是一种非常快速的操作方式。您可以使用它来解决您自己的特定问题,甚至可以对此进行改进,尤其是“多次读取”是您可以查看的内容,并在找到一个编码后立即打开文件。
答案 1 :(得分:1)
如果他们有混合编码,您可以尝试一种编码并回退到另一种编码:
# first open as binary
with open(..., 'rb') as f:
f_contents = f.read()
try:
contents = f_contents.decode('UTF-8')
except UnicodeDecodeError:
contents = f_contents.decode('gbk')
...
如果它们是html文件,您也可以找到编码标签,或者使用二进制正则表达式将它们搜索为二进制文件:
contents = open(..., 'rb').read()
regex = re.compile(b'http://.+\.jpg')
result = regex.findall(contents)
# now you'll probably want to `.decode()` each of the urls, but you should be able to do that pretty trivially with even the `ASCII` codec
虽然现在我想起来了,你可能真的不想使用正则表达式来捕获链接,因为你必须处理html实体(&
)并且可能会这样做更好用pyquery
这是使用pyquery
的快速示例contents = open(..., 'rb').read()
pq = pyquery.PyQuery(contents)
images = pq.find('img')
for img in images:
img = pyquery.PyQuery(img)
if img.attr('src').endswith('.jpg')
print(img.attr('src'))
安装有物品的计算机上没有,所以使用这些代码示例的里程可能会有所不同