Jsoup库使用:contains选择器时因文本含单引号触发‘Did not find balanced marker’错误的解决方案咨询
解决Jsoup选择器中包含单引号文本的匹配问题
这个问题的核心是直接将含特殊字符的变量拼进CSS选择器字符串,破坏了选择器的语法结构。当currentTitle里有单引号时,拼接后的选择器会变成类似a[class="class-name"]:contains(I'm here)——这里:contains()里的单引号和文本中的单引号没有正确配对,Jsoup解析时自然会报错。
最稳妥的解决方案:分离选择器与文本判断
不要把变量直接嵌入选择器,而是先选中所有符合class的<a>元素,再用代码过滤出包含目标文本的元素。Groovy的集合操作很适合做这件事,代码修改如下:
def get_url() { String url = "https://www.website.com/" GlobVars.currentPageSource = Jsoup.connect(url).get() // 先选中所有目标class的a元素,再过滤文本包含currentTitle的项 Elements wElements = GlobVars.currentPageSource.select('a[class="class-name"]').findAll { it.text().contains(GlobVars.currentTitle) } if(wElements) { // Do stuff... } }
这种方法完全避开了CSS选择器的语法限制,不管currentTitle里有单引号、双引号还是其他特殊字符,都能正常工作,而且代码可读性也更强。
备选方案:转义单引号(仅当必须使用:contains()时)
如果你一定要用CSS选择器的:contains()语法,需要把currentTitle里的单引号转义成CSS选择器能识别的格式。在Groovy中,你需要把文本里的'替换成\\'(因为反斜杠在字符串里需要转义),代码如下:
def get_url() { String url = "https://www.website.com/" GlobVars.currentPageSource = Jsoup.connect(url).get() // 转义文本中的单引号 String escapedTitle = GlobVars.currentTitle.replace("'", "\\'") // 使用双引号包裹选择器字符串,避免和内部的单引号冲突 Elements wElements = GlobVars.currentPageSource.select("a[class=\"class-name\"]:contains('${escapedTitle}')") if(wElements) { // Do stuff... } }
不过这种方法只解决了单引号的问题,如果文本里还有其他CSS选择器的特殊字符(比如:、[等),还是可能触发语法错误,所以更推荐第一种方案。
内容的提问来源于stack exchange,提问作者Simos Sigma
相关产品推荐
相关产品推荐

