使用Nokogiri时多条件CSS选择器报错问题求助
问题:Nokogiri合并CSS子选择器触发语法错误
在使用Nokogiri解析HTML时,需要查找两类<tr>节点:
<table>的直接子节点<tr><table>直接子节点<thead>的直接子节点<tr>
单独使用选择器> tr和> thead > tr调用search方法均可成功获取对应节点,但合并为> tr, > thead > tr时,触发Nokogiri::CSS::SyntaxError语法错误。
环境信息:
- Ruby版本:2.7.0
- Nokogiri版本:1.13.6
相关代码:
#!/usr/bin/ruby -w require 'nokogiri' puts RUBY_VERSION #=> 2.7.0 puts Nokogiri::VERSION #=> 1.13.6 html = <<~'HTML' <html> <body> <table> <thead> <tr> <th>city</th> <th>state</th> <th>classification</th> </tr> </thead> <tr> <th>Blacksburg</th> <td>Virginia</td> <td>College</td> </tr> </table> </body> </html> HTML doc = Nokogiri::HTML(html) table = doc.at('table') puts table.search('> tr').length #=> 1 puts table.search('> thead > tr').length #=> 1 puts table.search('> tr, > thead > tr').length #=> 触发错误
报错信息:
Traceback (most recent call last): 12: from ./parse.rb:36:in `<main>' 11: from /var/lib/gems/2.7.0/gems/nokogiri-1.13.6-x86_64-linux/lib/nokogiri/xml/searchable.rb:54:in `search' 10: from /var/lib/gems/2.7.0/gems/nokogiri-1.13.6-x86_64-linux/lib/nokogiri/xml/searchable.rb:54:in `map' 9: from /var/lib/gems/2.7.0/gems/nokogiri-1.13.6-x86_64-linux/lib/nokogiri/xml/searchable.rb:55:in `block in search' 8: from /var/lib/gems/2.7.0/gems/nokogiri-1.13.6-x86_64-linux/lib/nokogiri/xml/searchable.rb:245:in `xpath_query_from_css_rule' 7: from /var/lib/gems/2.7.0/gems/nokogiri-1.13.6-x86_64-linux/lib/nokogiri/xml/searchable.rb:245:in `map' 6: from /var/lib/gems/2.7.0/gems/nokogiri-1.13.6-x86_64-linux/lib/nokogiri/xml/searchable.rb:246:in `block in xpath_query_from_css_rule' 5: from /var/lib/gems/2.7.0/gems/nokogiri-1.13.6-x86_64-linux/lib/nokogiri/css.rb:46:in `xpath_for' 4: from /var/lib/gems/2.7.0/gems/nokogiri-1.13.6-x86_64-linux/lib/nokogiri/css/parser_extras.rb:78:in `xpath_for' 3: from /var/lib/gems/2.7.0/gems/nokogiri-1.13.6-x86_64-linux/lib/nokogiri/css/parser_extras.rb:68:in `parse' 2: from (eval):3:in `do_parse' 1: from (eval):3:in `_racc_do_parse_c' /var/lib/gems/2.7.0/gems/nokogiri-1.13.6-x86_64-linux/lib/nokogiri/css/parser_extras.rb:86:in `on_error': unexpected '> ' after ', ' (Nokogiri::CSS::SyntaxError)
解决方案
问题原因
Nokogiri 1.13.6版本的CSS解析器存在兼容性问题:当使用逗号分隔多个选择器时,不允许每个选择器都以子组合器>开头(尽管单独使用> tr这类选择器是合法的),解析器会将逗号后的>识别为语法错误。
可行解决方法
分开调用
search再合并结果
分别获取两类节点后合并,绕开解析器的语法限制:puts (table.search('> tr') + table.search('> thead > tr')).length #=> 2改用XPath表达式
XPath支持直接使用|操作符实现“或”逻辑,Nokogiri对XPath的处理更稳定:puts table.xpath('./tr | ./thead/tr').length #=> 2升级Nokogiri版本
Nokogiri 1.14.0及以上版本修复了该CSS选择器解析问题,升级后可直接使用合并后的选择器:puts table.search('> tr, > thead > tr').length #=> 2
内容的提问来源于stack exchange,提问作者tscheingeld
相关产品推荐
相关产品推荐

