Проблемы с htmlparser - PullRequest
       14

Проблемы с htmlparser

1 голос
/ 04 ноября 2011

Мне нужно извлечь один тег со страницы (которая содержит несколько дочерних элементов), а затем разделить полученный текст по тегам, которые содержат несколько звездочек (*). Мне нужно удалить теги со звездами, а затем разбить текст на части, которые я хотел бы сохранить в StringArray.

Ранее я использовал http://htmlparser.sourceforge.net/, и он отлично работал для извлечения текста из определенных тегов.

public class ToeGuideParser extends NodeVisitor{

private static final String TAG = "ToeGuideParser";
final String url = "http://p7510.teamovercome.net/?page_id=18";
private String Guide;
Context context;
int tag_number = 0;

public ToeGuideParser () throws ParserException{
    this(null);
}

public ToeGuideParser(Context context) throws ParserException{
    context = this.context;

    long bfr = startStopWatch();

    Parser parser = new Parser (url);
    parser.visitAllNodesWith(this);

    stopStopWatch(bfr);
}

public void visitTag (Tag tag){
    String tagName = tag.getTagName();
    String content = tag.toPlainTextString(); 
    //Log.d(TAG, tagName);
    if (tagName.equalsIgnoreCase("div")){
        Attribute attr = tag.getAttributeEx("class");
        if (attr!=null){
            String value = attr.getValue();
            if (value.equals("entry-content")){
                //save
                Guide = tag.toHtml(true);
                int guide_start = tag.getStartingLineNumber();
                int guide_end = tag.getEndingLineNumber();
                Log.d(TAG, "Guide starts at "+guide_start+" and ends at "+guide_end);
                //Log.d(TAG, Guide);
            }
        }
    }
    if (content.contains("*****")){
        tag_number++;
        int start = tag.getStartingLineNumber();
        int end = tag.getEndingLineNumber();
        Log.d(TAG, tag_number+" = Tag found at "+start+", ends at "+end);
    }
}

private void split (String bfrSplit){
    if (bfrSplit != null){
        //Log.d(TAG, bfrSplit);
        Pattern pattern = Pattern.compile("<([A-Z][A-Z0-9]*).*>[*]+</\1>", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(bfrSplit);
                while (matcher.find()){
                    Log.d(TAG,"Start index: " + matcher.start());
                    Log.d(TAG," End index: " + matcher.end() + " ");
                    Log.d(TAG,matcher.group());
                }
    }
}



public void finishedParsing(){
    //split(Guide);
    Log.w(TAG, "#########");
    Log.w(TAG, "finished");
}

public long startStopWatch(){
    return System.currentTimeMillis();
}

public String stopStopWatch(long bfr){
    long time = System.currentTimeMillis()-bfr;
    String formatedTime = "Time Taken: "+time+" milli's" ;
    Log.i(TAG, formatedTime);
    return formatedTime;
}

}

public long startStopWatch(){
    return System.currentTimeMillis();
}

public String stopStopWatch(long bfr){
    long time = System.currentTimeMillis()-bfr;
    String formatedTime = "Time Taken: "+time+" milli's" ;
    Log.i(TAG, formatedTime);
    return formatedTime;
}

}

Проблемы с этим кодом:

  • Возвращенные номера строк абсолютно неверны. (есть четные номера строк перед основной темой, которые совпадают)
  • Регулярное выражение никогда не совпадает, хотя я попробовал его в регулярном выражении с исходным кодом страницы. Я только попробовал регулярное выражение, потому что код с htmlparser не работает.

Stacktrace для иллюстрации:

D / ToeGuideParser ( 2146): 1 = Tag found at 11, ends at 11
D / ToeGuideParser ( 2146): 2 = Tag found at 201, ends at 201
D / ToeGuideParser ( 2146): 3 = Tag found at 202, ends at 202
D / ToeGuideParser ( 2146): 4 = Tag found at 237, ends at 237
D / ToeGuideParser ( 2146): 5 = Tag found at 238, ends at 238
D / ToeGuideParser ( 2146): 6 = Tag found at 239, ends at 239
D / ToeGuideParser ( 2146): Guide starts at 248 and ends at 248
D / ToeGuideParser ( 2146): 7 = Tag found at 248, ends at 248
D / ToeGuideParser ( 2146): 8 = Tag found at 261, ends at 261
D / ToeGuideParser ( 2146): 9 = Tag found at 261, ends at 261
D / ToeGuideParser ( 2146): 10 = Tag found at 280, ends at 280
D / ToeGuideParser ( 2146): 11 = Tag found at 280, ends at 280
D / ToeGuideParser ( 2146): 12 = Tag found at 307, ends at 307
D / ToeGuideParser ( 2146): 13 = Tag found at 318, ends at 318
D / ToeGuideParser ( 2146): 14 = Tag found at 322, ends at 322
D / ToeGuideParser ( 2146): 15 = Tag found at 328, ends at 328
D / ToeGuideParser ( 2146): 16 = Tag found at 350, ends at 350
D / ToeGuideParser ( 2146): 17 = Tag found at 367, ends at 367
D / ToeGuideParser ( 2146): 18 = Tag found at 376, ends at 376
W / ToeGuideParser ( 2146): #########
W / ToeGuideParser ( 2146): finished
I / ToeGuideParser ( 2146): Time Taken: 1021 milli's

1 Ответ

1 голос
/ 06 ноября 2011

Для проблемы с номерами строк: Я предполагаю, что вам интересно, почему вы получаете столько строк, которые говорят "Тег найден в" - их больше, чем васожидается.Проблема в том, что эта строка эффективно загружает большую часть HTML-страницы в одну строку:

    String content = tag.toPlainTextString(); 

Метод toPlainTextString() включает текстовое содержимое дочерних тегов, поэтому все родительские теги тегасодержащие ***** собираются содержать также *****.Я думаю, что вы, вероятно, захотите использовать getText() вместо этого, который не включает текст дочерних элементов (см. JavaDoc ).

Обратите внимание, что использование toPlainTextString(), как это лучше избегатьпотому что это будет довольно медленно.Поскольку он вызывается для каждого тега в документе, возможно, вы заставляете документ читать его сто раз, без необходимости ...

Для проблемы с регулярным выражением: Вы на самом деле невызов метода split(), который в данный момент содержит регулярное выражение.Но если бы вы были, я предполагаю, что это потерпит неудачу, потому что он пытается сопоставить как начальный тег, текстовый узел и конечный тег.Но HTML Parser дает вам только один узел за раз, то есть:

  • visitTag() дает вам только начальный тег
  • visitStringNode() дает вам только текстовый узел
  • visitEndTag() дает вам только конечный тег

Таким образом, ваше регулярное выражение потерпит неудачу, потому что ожидает получить начало, текст и конец сразу.Кроме того, я думаю, что вам нужно избегать сопоставления звездочек следующим образом: [\*]+

Если вам нужно сопоставить что-либо по всем трем узлам, то вам нужно добавить некоторые частные переменные в ваш класс для записи состояния.то есть, если visitTag() соответствует желаемому тегу, тогда установите логическое значение, говорящее о том, что текущий тег является действительным ... тогда, когда вызывается visitStringNode(), он может проверить этот логический параметр, чтобы решить, обрабатывать ли текст или игнорировать его.Затем сбросьте логическое значение, когда вы встретите конечный тег.

...