【问题标题】:jsoup throwing IndexOutOfBoundsException on element.remove()jsoup 在 element.remove() 上抛出 IndexOutOfBoundsException
【发布时间】:2016-06-05 19:15:45
【问题描述】:

我正在编写一个清理网页的脚本。这包括遍历所有标签(元素)并检查某些规则:

    for (Element element :  document.select("*") ) {
        if (element == null) { 
            continue;
        }


        if ( RULE1) ) {
            element.remove();
        }


        else if( RULE2){
            element.remove();
        }


        else if ( RULE3 ) {
            element.remove();
        }

        else if (  RULE4 ) {
            element.remove();
        }

    }   

我已经在几十页上对此进行了测试,没有任何问题。今天我刚打了一个网页抛出java.lang.IndexOutOfBoundsException

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 1
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.remove(ArrayList.java:492)
    at org.jsoup.nodes.Node.removeChild(Node.java:423)
    at org.jsoup.nodes.Node.remove(Node.java:266)

我的猜测是,在某些时候,代码会尝试删除已删除的元素。但不知道如何/为什么会发生这种情况。

有什么想法吗?

谢谢。

编辑 1:导致中断的规则

我发现了导致代码失败的规则。其中一条规则实际上并未删除element,而是重置其文本:

        else if ( matches junk text ) {
            String match = getMatchingJunk ( element.ownText() );
            if ( match.length()  < JUNK_TEXT_ELEMENT_REMOVAL_THRESH ) {
                element.text( removeSmallest(element.ownText(), match) ); // <= causing error
                continue;
            }

            element.remove();

        }

如果我删除element.text( removeSmallest(element.ownText(), match) ) 行,错误就会消失。

【问题讨论】:

    标签: java arrays html-parsing jsoup


    【解决方案1】:

    如果我分两个阶段清除垃圾文本,代码似乎可以工作。代码看起来有点重复和hackish。可能有更好的方法来做到这一点:

    第一阶段:收集所有垃圾

            Map <String, Element> junks = new HashMap <String, Element>();
            for (Element element :  document.select("*") ) {
                ...
    
                if () {
                    ...
                }
    
                else if ( matches junk text ) {
                    String match = getMatchingJunk ( element.ownText() );
                    if ( match.length()  < JUNK_TEXT_ELEMENT_REMOVAL_THRESH ) {
                        //element.text( removeSmallest(element.ownText(), match) ); // <= causing error
                        junks.put(elOwnText,element);
                        continue;
                    }
    
                    element.remove();
    
                }
            }
    

    第二阶段:清除垃圾

        if ( size(junks) > 0 ) {
            for(Map.Entry<String,Element> ent : junks.entrySet()){
    
                String match = getMatchingJunk (ent.getKey()); // this looks repetitive. probably there's a better way to do it
                if ( match.length()  < JUNK_TEXT_ELEMENT_REMOVAL_THRESH ) {
                    ent.getValue().text( removeSmallest(ent.getKey(), match) ); // purge junk
    
                }
            } // end for
        } // end if
    

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-31
      • 2020-05-11
      • 2021-12-20
      相关资源
      最近更新 更多