如何在不编码的情况下读取文件并使用python3提取所需的URL?

时间:2017-06-07 03:27:14

标签: python-3.x file encoding utf-8

环境: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网址。

2 个答案:

答案 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'))

安装有物品的计算机上没有,所以使用这些代码示例的里程可能会有所不同