四、python-docx中paragraph处理超链接

本文介绍了如何在Python-docx中实现插入、获取和修改Word文档中的超链接,包括自定义add_hyperlink函数、get_hyperlinks函数以及修改超链接文本和URL的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、插入超链接

        在段落中插入超链接,目前python-docx没有提供现成的方法(截止到1.1.0版本),不像 add_run() 这么简单,没有add_hyperlink()这样的方法。我们可以自己封装一个add_hyperlink()方法用于在段落中插入超链接。

import docx
from docx.enum.dml import MSO_THEME_COLOR_INDEX

def add_hyperlink(paragraph, text, url):
    # 获取paragraph的part对象,并且创建一个新的关系
    part = paragraph.part
    r_id = part.relate_to(url, docx.opc.constants.RELATIONSHIP_TYPE.HYPERLINK, is_external=True)

    # 创建 w:hyperlink 标签并且添加所需的值
    hyperlink = docx.oxml.shared.OxmlElement('w:hyperlink')
    hyperlink.set(docx.oxml.shared.qn('r:id'), r_id, )

    # 创建一个 w:r 元素 和一个 w:rPr 元素
    new_run = docx.oxml.shared.OxmlElement('w:r')
    rPr = docx.oxml.shared.OxmlElement('w:rPr')

    # 把所有的 xml 元素合并到一起,并且添加显示的文本给 w:r 元素
    new_run.append(rPr)
    new_run.text = text
    hyperlink.append(new_run)

    # 创建一个新的 Run 对象并且添加新的超链接进去
    r = paragraph.add_run()
    r._r.append(hyperlink)

    # 设置超链接的样式,样式颜色为超链接,并且文本有下划线
    r.font.color.theme_color = MSO_THEME_COLOR_INDEX.HYPERLINK
    r.font.underline = True

    return hyperlink


document = docx.Document()

p = document.add_paragraph('这是一段话中的第一句,')
add_hyperlink(p, '跳转到baidu', 'https://www.baidu.com')
p.add_run(',这是第二句 ')

p2 = document.add_paragraph('这是第二段')

document.save('demo_hyperlink.docx')

运行效果如下:

2、获取超链接

        直接读取 paragraph.text 或者 直接读取 run.text,都是无法获得超链接内容的,如下图。

        因为超链接(hyperlink)是paragraph的一个子项,和Run是平级的。hyperlink本身包含Runs,超链接的文本存在Runs的text里。

2.1、获取超链接(包括文本和url)

# 2、获取超链接
import docx
from docx.enum.dml import MSO_THEME_COLOR_INDEX
from docx.opc.constants import RELATIONSHIP_TYPE as RT

def get_hyperlinks():
    import re
    d = docx.Document('demo_hyperlink.docx')

    # 存放超链接URL
    target = {}
    # 存放超链接文本
    text = {}

    # 获取超链接
    rels = d.part.rels
    for rel in rels:
        if rels[rel].reltype == RT.HYPERLINK:
            id = rels[rel]._rId
            target[id] = rels[rel]._target

    # 获取超链接文本
    for p in d.paragraphs:
        # 将文档处理为xml,并转为字符串
        xml = p.paragraph_format.element.xml
        xml_str = str(xml)
        # print(xml_str)
        # 获取文本中由<w:hyperlink>标签包起来的部分
        hl_list = re.findall('<w:hyperlink[\S\s]*?</w:hyperlink>', xml_str)
        for hyperlink in hl_list:
            # 获取rId
            rid = re.search(r'r:id="(.*?)"', hyperlink).group(1)
            # 获取文本中由<w:t>标签包起来的部分
            wt_list = re.findall('<w:t[\S\s]*?</w:t>', hyperlink)
            # print(wt_list)
            temp = u''
            for wt in wt_list:
                # 去掉<w:t>标签
                wt_content = re.sub('<[\S\s]*?>', u'', wt)
                temp += wt_content
            text[rid] = temp

    results = []
    for t in text.keys():
        tmp_rel = { 'id':t, 'url':target[t],'text':text[t] }
        results.append(tmp_rel)
    # print(results)
    return results
    pass

运行结果:

2.2、获取超链接(仅文本) 

# 获取超链接
d = docx.Document('demo_hyperlink.docx')
for p in d.paragraphs:
    hls = p.hyperlinks
    for hlink in hls:
        for r in hlink.runs:
            print(f'text:{r.text}')

3、修改超链接

3.1、修改超链接文本

def edit_hyperlink_text():
    d = docx.Document('demo_hyperlink.docx')

    # 1、根据指定的文本,修改为目标文本
    origin_text = '示例一'
    target_text = '示例二'

    for p in d.paragraphs:
        for hlink in p.hyperlinks:
            # print(hlink.text)
            if hlink.text == origin_text:
                for r in hlink.runs:
                    r.clear()
                hlink.runs[0].text = target_text

    d.save('demo_hyperlink_1.docx')

原始文档如下:

代码运行后,“示例一” 修改为 “示例二”,效果如下:

3.2、修改超链接地址

def edit_hyperlink_url():
    # 2、根据指定的文本,修改为目标url
    origin_doc_name = 'demo_hyperlink_1.docx'
    d = docx.Document(origin_doc_name)
    hyperlinklist = get_hyperlinks(origin_doc_name)
    print(hyperlinklist)
    origin_text = '示例二'
    target_url = 'https://www.qq.com'

    ids = []
    for hll in hyperlinklist:
        if hll['text'] == origin_text:
            print(rf"id={hll['id']}, url={hll['url']}, text={hll['text']}")
            ids.append(hll['id'])

    rels = d.part.rels
    for rel in rels:
        if rels[rel].reltype == RT.HYPERLINK:
            id = rels[rel]._rId
            if id in ids:
                rels[rel]._target = target_url
                print(rels[rel]._target)
    d.save('demo_hyperlink_2.docx')

原始文档如下:

代码运行后,修改“示例二”的url地址为 www.qq.com,效果如下:

4、删除超链接

4.1、方法一:把超链接的内容置空

使用python-docx删除超链接时,由于无法删除run,所以可以使用一种变通的方式,即把超链接的文本置为空,达到删除超链接的效果。

def remove_hyperlink():
    d = docx.Document('demo_hyperlink.docx')

    # 删除超链接
    origin_text = '示例一'
    target_text = ''

    for p in d.paragraphs:
        for hlink in p.hyperlinks:
            print(hlink.text)
            if hlink.text == origin_text:
                for r in hlink.runs:
                    r.clear()
                hlink.runs[0].text = target_text

    d.save('demo_hyperlink_1.docx')

原始文件内容:

代码运行后,删除 “示例一” 这个超链接,效果如下:

4.2、方法二:把超链接这个对象移除

 第二种方法是把 Paragraph里的hyperlink对象移除

def remove_hyperlinks():
    doc = docx.Document('demo_hyperlink.docx')
    for paragraph in doc.paragraphs:
        # 查找超链接
        hyperlinks = [child for child in paragraph._element.getchildren() if child.tag.endswith('hyperlink')]
        for hyperlink in hyperlinks:
            # 删除超链接
            paragraph._element.remove(hyperlink)
    doc.save('demo_hyperlink_3.docx')

原始文件内容如下:

代码运行后效果如下:

 

5、取消超链接

用普通文本替换掉超链接,即把原文本上的超链接去除。

思路:

1、获取超链接的文本和url

2、移除超链接

3、插入文本

4、保存文档

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jerry_xizn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值