Python中replace替换富文本编辑器中的url却匹配不到的问题如何解决
因为微信的图片有防盗链机制,复制粘贴文章每次图片都要重新传,感觉很麻烦,就想覆写下 django admin 的 save_model 方法,打算把复制来的文章的图片存到本地,如下
def save_model(self, request, obj, form, change):
b = etree.HTML(obj.content)
pics = b.xpath("//*/@src")
for pic in pics:
c = pic.split("&")[0].split("=")
if c[1] == "jpeg" or c[1] == "png" or c[1] == "jpg":
img_url = pic.split("&")[0]
image_name = img_url.replace("https://","").split("/")[2]
new_name = settings.MEDIA_ROOT+"/"+image_name+"."+c[1]
file_name = settings.MEDIA_URL+image_name+"."+c[1]
response = requests.get(img_url)
image = Image.open(BytesIO(response.content))
image.save(new_name)
obj.content = obj.content.replace(str(pic),str(file_name))
print(pic)
super(NewsAdmin,self).save_model(request, obj, form, change)
问题就出现在这句
obj.content = obj.content.replace(str(pic),str(file_name))
想要把 富文本编辑内的原图片 url 替换成 新生成的 url 原地址也是通过 xpath 取出来的 所以应该是没有问题的 但是 replace 就是一直匹配不到原 url 即使加了去掉换行符,依旧匹配不到
obj.content = obj.content.replace('\r','').replace('\n','').replace('\t','')
有点懵了,还请各位指点一下
Python中replace替换富文本编辑器中的url却匹配不到的问题如何解决
2 回复
我遇到过这个问题,富文本编辑器生成的HTML里URL经常被各种属性包裹,直接匹配纯文本URL确实会失败。
核心问题是富文本中的URL通常被包装在HTML标签里,比如:
text = '<a href="https://example.com/page?id=123">点击这里</a>'
# 直接replace("https://example.com/page?id=123", "new_url") 是匹配不到的
你需要用正则表达式处理HTML内容:
import re
def replace_url_in_html(html_content, old_url, new_url):
"""
在HTML内容中安全替换URL
参数:
html_content: 包含HTML的字符串
old_url: 要替换的原始URL
new_url: 替换后的新URL
"""
# 转义特殊字符,确保正则匹配安全
escaped_old_url = re.escape(old_url)
# 匹配各种可能包含URL的HTML属性
patterns = [
rf'href=["\']{escaped_old_url}["\']', # href属性
rf'src=["\']{escaped_old_url}["\']', # src属性
rf'url\({escaped_old_url}\)', # CSS url()中的URL
]
for pattern in patterns:
html_content = re.sub(
pattern,
lambda m: m.group(0).replace(old_url, new_url),
html_content,
flags=re.IGNORECASE
)
return html_content
# 使用示例
html = '<a href="https://old.com/page">链接</a><img src="https://old.com/image.jpg">'
new_html = replace_url_in_html(html, "https://old.com/", "https://new.com/")
print(new_html)
如果富文本内容特别复杂,建议用专门的HTML解析库:
from bs4 import BeautifulSoup
def replace_url_with_bs4(html_content, old_url, new_url):
soup = BeautifulSoup(html_content, 'html.parser')
# 替换所有标签的href属性
for tag in soup.find_all(href=re.compile(re.escape(old_url))):
tag['href'] = tag['href'].replace(old_url, new_url)
# 替换所有标签的src属性
for tag in soup.find_all(src=re.compile(re.escape(old_url))):
tag['src'] = tag['src'].replace(old_url, new_url)
return str(soup)
关键是要理解富文本是HTML,不是纯文本。用字符串的replace()方法处理HTML就像用剪刀修电路板——工具用错了。
总结:用正则或HTML解析器处理富文本中的URL替换。
找到问题了…原 url 中有很多&…

