解析HTML文件并将找到的图片添加到ZIP文件中

2 投票
3 回答
1108 浏览
提问于 2025-04-15 17:17

我正在尝试从一个HTML文件中提取所有的图片标签(img),下载这些图片,并把它们放到一个压缩文件(zip文件)里。我希望这一切都在内存中完成,因为我可以保证图片的数量不会太多。

假设我已经从HTML中提取到了图片的相关信息,现在我需要帮助的是如何把这些图片放进压缩文件里。

from zipfile import ZipFile
from StringIO import StringIO
from urllib2 import urlopen

s = StringIO()
zip_file = ZipFile(s, 'w')
try:
    for image in images:
        internet_image = urlopen(image)
        zip_file.writestr('some-image.jpg', internet_image.fp.read())
        # it is not obvious why I have to use writestr() instead of write()
finally:
    zip_file.close()

3 个回答

1

我不太确定你在问什么,因为看起来你已经解决了大部分问题。

你有没有研究过 HtmlParser 来进行 HTML 解析呢?我建议你不要自己动手写解析器,这是一项非常复杂的工作,而且会遇到很多特殊情况。对于简单的情况,才考虑使用正则表达式。

对于每个 <img/> 标签,你可以使用 HttpLib 来获取每一张图片。为了加快压缩文件的生成,使用多个线程来获取图片可能会更有效。

1

我想到的最简单的方法就是使用BeautifulSoup这个库。

大概可以这样做:

from BeautifulSoup import BeautifulSoup
from collections import defaultdict

def getImgSrces(html):
    srcs = []
    soup = BeautifulSoup(html)

    for tag in soup('img'):
        attrs = defaultdict(str)
        for attr in tag.attrs:
            attrs[ attr[0] ] = attr[1]
        attrs = dict(attrs)

        if 'src' in attrs.keys():
            srcs.append( attrs['src'] )

    return srcs

这样你就能得到一个从你的img标签中提取出来的URL列表,可以用来循环处理。

1

关于你问的如何创建ZIP压缩文件的问题(其他人讨论的是解析网址),我测试了你的代码。你已经非常接近完成这个功能了。

下面是我建议你可以在现有代码基础上做的改进,以创建一个ZIP压缩文件(在这个例子中,我将压缩文件写入硬盘,以便我可以确认它是否正确写入)。

from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED
import zlib
from cStringIO import StringIO
from urllib2 import urlopen
from urlparse import urlparse
from os import path

images = ['http://sstatic.net/so/img/logo.png', 
          'http://sstatic.net/so/Img/footer-cc-wiki-peak-internet.png']

buf = StringIO()
# By default, zip archives are not compressed... adding ZIP_DEFLATED
# to achieve that. If you don't want that, or don't have zlib on or
# system, delete the compression kwarg
zip_file = ZipFile(buf, mode='w', compression=ZIP_DEFLATED)

for image in images:
    internet_image = urlopen(image)
    fname = path.basename(urlparse(image).path) 
    zip_file.writestr(fname, internet_image.read())

zip_file.close()

output = open('images.zip', 'wb')
output.write(buf.getvalue())
output.close()
buf.close()

撰写回答