Python-docx - 从 URL 将图片插入 docx
Posted
技术标签:
【中文标题】Python-docx - 从 URL 将图片插入 docx【英文标题】:Python-docx - insert picture into docx from URL 【发布时间】:2020-06-19 07:49:29 【问题描述】:我正在尝试抓取网站(例如 imgur)上托管的图像并将其添加到 docx。
这是我的初始代码(这是函数的一部分。我已将其剥离为相关代码):
from PIL import Image
from urllib.request import urlopen
thisParagraph = document.sections[0].paragraphs[0]
run = thisParagraph.add_run()
# imgLink is a direct link to the image. Something like https://i.imgur.com/<name>.jpg
# online is a parsed-in boolean to determine if the image link is from an image hosting site
# or from the local machine
if (online):
imgLinkData = urlopen(imgLink )
img = Image.open(imgLinkData )
width, height = img.size
else:
img = Image.open(imgLink )
width, height = img.size
imgLinkData = imgLink
if (width > 250) or (height > 250):
if (height > width):
run.add_picture(imgLinkData, width=Cm(3), height=Cm(4) )
else:
run.add_picture(imgLinkData, width=Cm(4), height=Cm(3) )
else:
run.add_picture(imgLinkData)
在大多数情况下,如果 imgLink 指向我的本地系统(即图像托管在我的 PC 上),则此方法有效。
但如果我引用一个 url 链接(online=True),我会得到各种类型的异常(我试图修复它),范围从 io.UnsupportOperation
(搜索)到 TypeError
(需要字符串参数,得到' bytes'),原因总是run.add_picture
行。
现在的代码会引发io.UnsupportOperation
异常。
【问题讨论】:
【参考方案1】:将图像保存到文件中,然后使用文件路径作为.add_picture()
的第一个参数。这大概是这样的:
img.save("my-image.jpg")
run.add_picture("my-image.jpg", width=Cm(3), height=Cm(4))
作为替代方案,您可以创建一个包含图像的“内存中”文件 (io.BytesIO
) 并使用它。第二种方法的优点是不需要访问文件系统。
import io
image_stream = io.BytesIO(imgLinkData)
run.add_picture(image_stream, width=Cm(3), height=Cm(4))
Document.add_picture()
的接口需要一个 str 路径或类似文件的对象(打开的文件或内存中的文件)作为其第一个参数:https://python-docx.readthedocs.io/en/latest/api/document.html#docx.document.Document.add_picture
【讨论】:
按照建议,我修改为:if (online): imgLinkData = urlopen(imgLink ) img = Image.open(imgLinkData ) width, height = img.size image_stream = io.BytesIO(imgLinkData)
我在该特定行得到了TypeError: a bytes-like object is required, not 'HTTPResponse'
。如果可能的话,我宁愿不将图像保存到机器上。【参考方案2】:
我想我可能已经解决了这个问题。
基于this link,我对自己的代码做了一些细微的修改。
我补充说:
import requests, io
然后我改变了:
imgLinkData = urlopen(imgLink )
到
imgLinkData= io.BytesIO(requests.get(imgLink ).content )
这似乎已经成功地在我的 docx 文档中生成了图像,虽然我不完全确定为什么,除了 urlopen 返回的事实
<class 'http.client.HTTPResponse'>
requests.get 返回
<class 'requests.models.Response'>
和 .content 返回一个
<class 'bytes'>
对象。
Further reading 甚至似乎表示反对使用urllib
【讨论】:
以上是关于Python-docx - 从 URL 将图片插入 docx的主要内容,如果未能解决你的问题,请参考以下文章