You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中Playwright使用:text-matches()正则匹配无结果求解

解决Playwright中大小写不敏感匹配含重音名称的问题

问题根源

你的代码里:text-matches失效主要有两个原因:

  1. Playwright的:text-matches用的是JavaScript正则引擎,不是Python的re模块。JS原生的\b只识别ASCII字符的单词边界,对带重音的Unicode字符(比如í、á)不生效,导致匹配不到目标文本。
  2. 正则标志没有开启Unicode支持,无法正确处理特殊字符。

方案一:修正JS正则适配Unicode

直接调整:text-matches的正则表达式,使用JS支持的Unicode单词边界判断,同时添加u标志开启Unicode模式:

import re
from playwright.async_api import async_playwright

names_to_find = ['almería', 'cádiz']

async def fetch_geojson(page, names_to_find):
    results = {}

    while names_to_find:
        for name in names_to_find[:]:
            # JS正则的Unicode单词边界:(?<!\p{L}) 匹配非字母前缀,(?!\p{L})匹配非字母后缀
            # 用re.escape处理名称里的特殊字符,确保在JS正则中生效
            pattern = rf"(?<!\p{L}){re.escape(name)}(?!\p{L})"
            # 添加"iu"标志:i=大小写不敏感,u=Unicode支持
            name_found = page.locator(f'td[data-label="nameunit"]:text-matches("{pattern}", "iu")').first

            if await name_found.count() > 0:
                print(f"{name} found!")
                results[name] = "GeoJSON_data_placeholder"
                names_to_find.remove(name)
                await page.goto("https://example.com")

    return results

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
        geojson_results = await fetch_geojson(page, names_to_find)
        await browser.close()

方案二:Python端做文本匹配(更可控)

如果JS正则调试麻烦,可以先获取所有目标元素,再在Python端用正则匹配,灵活性更高:

import re
from playwright.async_api import async_playwright

names_to_find = ['almería', 'cádiz']

async def fetch_geojson(page, names_to_find):
    results = {}
    target_names = set(names_to_find)

    while target_names:
        # 重新获取页面上的目标元素(跳转后需要刷新)
        elements = page.locator('td[data-label="nameunit"]')
        element_count = await elements.count()

        for i in range(element_count):
            element = elements.nth(i)
            text = await element.text_content()
            if not text:
                continue

            # 遍历剩余名称,大小写不敏感匹配完整单词
            for name in list(target_names):
                if re.search(rf"\b{re.escape(name)}\b", text, re.IGNORECASE):
                    print(f"{name} found!")
                    results[name] = "GeoJSON_data_placeholder"
                    target_names.remove(name)
                    await page.goto("https://example.com")
                    break
            if not target_names:
                break

    return results

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
        geojson_results = await fetch_geojson(page, names_to_find)
        await browser.close()

额外提示

  • 避免在循环中直接修改原列表,改用集合或者副本遍历,减少逻辑混乱。
  • 页面跳转后,之前的locator会失效,必须重新获取元素。
  • 可以先用await element.inner_text()或者text_content()打印实际文本,确认目标内容是否符合预期,排除选择器错误的可能。

内容的提问来源于stack exchange,提问作者Sofía Fayó

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:12:01