2012-01-14 5 views
0

Я использую Eclipse для разработки приложения для использования на Android 2.1, используя библиотеку ядра jsoup 1.6.1 для подключения к веб-странице и scrape html. До сих пор приложение, вставленное ниже, подключается к веб-странице через jsoup методом connect, создает документ с помощью метода jsoup get, затем выбирает всю таблицу строк Elements, а затем получает все элементы этой строки таблицы через jsoup getAllElements, (в этот случай, Элементы), проверяет их на текст и, если содержит определенную подстроку, преобразует текст в String через метод jsoup text и добавляет их в набор строк ListArray, отображая их в android ListView. Ниже приведены мои 2 вопроса, а затем код.Поиск в пределах <tr> таблица строк html с использованием jsoup в java для Android 2.1

Код, похоже, работает на моем эмуляторе, возвращая данные о строках, однако есть ошибка, в которой Android отображает каждую строку со строковой информацией в двух экземплярах, которую я не могу отслеживать.

Кроме того, я хотел знать, был ли более оптимальный метод для выполнения этих задач более быстрым способом с использованием jsoup или другой библиотеки java/android, и хотел узнать какие-либо предложения. Например, кажется, что когда я запускаю этот код на странице, содержащей много данных, это занимает немного больше времени, чем мне может понравиться. Например, я загружаю всю страницу и создаю jsoup doc перед выполнением любой операции над данными или возвращением любого из них пользователю. Если бы я подключился к странице, найдите первый элемент таблицы Row html, протестируйте дочерние элементы для текста, содержащего подстроку, я могу потенциально вернуть информацию конечному пользователю Android быстрее и с меньшими затратами на загрузку всего документа , Я не был уверен, какие методы jsoup будут доставлять что-то с этой целью.

Я очень новичок в jsoup и java, и несколько менее новый (но все же обучение) на других языках, таких как C и C#. Правильно форматирование вставленного текста оставило что-то нужное, и я не смог успешно использовать тэг prettify при просмотре в Chrome и заранее извинился, если я пропустил ввод символа или конечного блока во время копирования и вставки теста. Еще раз спасибо.

Jsoupx1.Activity.java

package jsoup.example1; 
    import java.io.IOException; 
    import java.util.ArrayList; 
    import android.app.ListActivity; 
    import android.os.Bundle; 
    import org.jsoup.Jsoup; 
    import org.jsoup.nodes.Document; 
    import org.jsoup.nodes.Element; 
    import org.jsoup.select.Elements; 
    import android.widget.ArrayAdapter; 
    import android.widget.ListView; 
    import android.widget.Toast; 
    import android.view.View; 

    public class Jsoupx1Activity extends ListActivity { 

    public void onCreate(Bundle icicle) { 
      super.onCreate(icicle); 


    //ArrayList tableRowStrings will be the recipient of table row data that matches a search criterion, 
    //stored in the form of strings. 
    ArrayList<String> tableRowStrings = new ArrayList<String>(); 

    //Open a document from a valid URL using jsoup 
    Document doc = null; 
      try { 
       doc = Jsoup.connect("http://www.w3schools.com/html/html_tables.asp").get(); 

      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


      //Once this document has loaded, select all <tr> tableRow elements into tableRows, with each 
      //tableRow, collect all children, which will be <td>, into tableDatas Elements, test that Elements class for text, 
      //if text exists, transfer the text of these children to a string, test that string for a substring, 
      //In this case, a date, if it contains this substring, add it to the created tableRowStrings ArrayList. 
      //This function falsely returns a string with duplicated table row information. 

      //Example Test Criteria, in reality this may be interfaced to a datetime or textbox widget 
      //to facilitate an end-user defined search 
      String testString = "Apples"; 

      //select all <tr> or Table Row Elements 
      Elements tableRows = doc.select("tr"); 

      //Load ArrayList with table row strings 
      for (Element tableRow : tableRows){ 

       Elements tableDatas = tableRow.getAllElements(); 

       //Test if the the TableData contains Text, if so convert that text to a string rowData 
       if (tableDatas.hasText()){ 
        String rowData = tableDatas.text(); 

        if (rowData.contains(testString)){ 
         tableRowStrings.add(rowData); 
        } 

       } 

     } 

      ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
        android.R.layout.simple_list_item_1, tableRowStrings); 
      setListAdapter(adapter); 
     } 

    @Override 
     protected void onListItemClick(ListView l, View v, int position, long id) { 
      String item = (String) getListAdapter().getItem(position); 
      Toast.makeText(this, item + " selected", Toast.LENGTH_LONG).show(); 
     } 
    } 

И сопутствующая main.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

<TextView 
    android:id="@+id/text" 
    android:textStyle="bold" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    /> 


<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:padding="10dp" 
    android:textSize="16sp" > 
</TextView> 

<ListView 
    android:id="@+android:id/list" 
    android:layout_width="fill_parent" 
    android:textColor="#444444" 
    android:cacheColorHint="#00000000" 
     android:layout_height="wrap_content" 
> 
</ListView> 

</LinearLayout> 

ответ

0

Чтобы устранить проблему, где строка была дублированных копий данных таблицы, я заменил логику внутри foreach блок. Предыдущая версия неправильно выполняет:

Elements tableDatas = tableRow.getAllElements(); 

//Test if the the TableData contains Text, if so convert that text to a string rowData 
     if (tableDatas.hasText()){ 
      String rowData = tableDatas.text(); 

      if (rowData.contains(testString)){ 
       tableRowStrings.add(rowData); 
      } 

     } 

Обновленная версия:

if (tableRow.hasText()){ 
    String rowData = tableRow.text(); 
    if(rowData.contains(testString)){ 
     tableRowStrings.add(rowData); 
    } 
} 

Это, кажется, чтобы решить эту проблему. Сейчас это выглядит немного быстрее. Я не уверен, почему он собирал 2 копии табличных данных в предыдущей версии, и я думаю, именно поэтому я, возможно, назвал это ошибкой, что может быть неверно, а просто мое непонимание кода.

По вопросам производительности, возможно, часть его касается моего недостатка понимания с сборщиком мусора java. Например, в моем коде, как только я создал document и извлек нужный Elements, будет ли сборщик мусора подсчитать, что у меня больше нет операций для document и удалить его?

Единственный другой насущный вопрос, который у меня есть, - это способ открыть соединение с веб-сайтом, начать очищать и возвращать первое совпадение конечному пользователю с помощью андроида ListView и продолжать поиск в html-документе, а затем обновить ListView, если/когда расположены более подходящие элементы?

0

Вернувшись к документации jsoup, выясняется, что метод Jsoup.connect(String url) просто предоставляет интерфейс к веб-странице или файлу html, а не загружает весь документ. get() выполняет запрос как GET и анализирует результат, возвращая анализируемый документ. Выполняя некоторые испытания, операция Jsoup.connect().get() потребляет больше всего времени. Это не похоже на то, что любой из других параметров Jsoup позволит детализации разбора быстрее доставлять контент. Другим вариантом было бы попробовать другую библиотеку или использовать подход Web Dyno и метод Jsoup.connect().post() для подключения к веб-странице прокси-сервера, которая сама предоставила бы функциональность скремблирования по строкам приложения Android в следующем сообщении в блоге, приведенном ниже , Я просто жду, пока требуемый 24-часовой период истечет, поэтому я могу принять ответ, если только я не хочу просто удалить этот пост, я был не совсем уверен ... http://ifdefined.com/blog/post/A-Hacker-News-app-for-Android.aspx