Jsoup parsing

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 13:41

Вопрос по библиотеке Jsoup. (оф сайт: http://jsoup.org)
Смог по (http://developer.alexanderklimov.ru/and ... php#common) этому уроку прочитать заголовок страницы из интернета. Теперь у меня есть сайт с кучей CSS кодов (a hreg, center и т.д.). Надо выделить определенную часть текста. Если кто работал с CSS-селектором библиотеки Jsoup, отпишитесь сюда.
Вот пример с официального сайта:

Код: Выделить всё

File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");

Elements links = doc.select("a[href]"); // a with href
Elements pngs = doc.select("img[src$=.png]");
  // img with src ending .png

Element masthead = doc.select("div.masthead").first();
  // div with class=masthead

Elements resultLinks = doc.select("h3.r > a"); // direct a after h3
Еще интересует дальнейший вывод списка в Listview.
Жду советов. А пока буду сам разбираться и если найду решение-напишу.

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 14:58

Вот еще что нашел(источник: http://www.codeproject.com/Articles/209 ... -using-CSS):

Код: Выделить всё

 try {
            File input = new File("input/dZoneLinks.xml");
            Document doc = Jsoup.parse(input, "UTF-8",
                    "http://www.dzone.com/links/?type=html&p=2");

            Elements descriptions = doc.select("div.details > p.description");
            // get all description elements in this HTML file
            for (Element element : descriptions) {
                System.out.println(element.ownText());
                System.out.println("--------------");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
Теперь надо разобраться как это вывести в TextView...
Последний раз редактировалось Xpert043 19 июн 2012, 15:16, всего редактировалось 1 раз.

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 15:16

Вот еще меньший "кусочек" программы:

Код: Выделить всё

Document doc = null;
		try {
            File input = new File("input/FILE.xml");
            doc = Jsoup.parse(input, "UTF-8","http://www.dzone.com/links/?type=html&p=2");
            Elements descriptions = doc.select("div.details > p.description");
       } catch (Exception e) {
            e.printStackTrace();
        }
		String linkHref = doc.attr("href"); 
		tvInfo.setText(linkHref); 
Вопрос: как выводить текст полученный в Elements? На main.xml имею только textview.

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Jsoup parsing

Сообщение Prospekt » 19 июн 2012, 18:08

Я не работал с данной библиотекой, но
Не могли бы вы как-нибудь попонятней объяснить саму задачу и возникшие проблемы. Три раза читал, ничего не понял, совсем дурной однако я стал. :)

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 18:45

Есть какой нибудь вот такой код(исходный код страницы форума):
td id="ph-12977071-d2" class="row2" valign="middle" width="99%">
<!-- POSTED DATE DIV -->
<div style="float: left;">
<span class="postdetails"> <img src="http://s.4pda.ru/forum/style_images/1/to_post_off.gif" alt="" border="0" style="padding-bottom:2px" /> 03.05.2012, 20:24</span>
</div>
<!-- REPORT / DELETE / EDIT / QUOTE DIV -->
<div style="float:left;margin-left:50px;" id="kh-12977071"></div>
<div align="right">
<span class="postdetails">Сообщение <a title="Ссылка на это сообщение" href="/forum/index.php?showtopic=286021&view=findpost&p=12977071" onclick="link_to_post(12977071); return false;">#1</a></span>
</div>
</td>
Задача с помощью CSS-селекторов, которые поддерживаются библиотекой Jsoup извлечь элементы текста или ссылок. Выше в постах я выкладывал какие то примеры, которые находил в интернете. А Elements, это тот параметр, который выделяет кусочек текста с определенными тегами ("a href" "div" и другие). У меня задача в том, чтобы то что выделил Elements из общей кучи текста, вывести в TextView на моей форме.
Надеюсь понятно объяснил. Если все равно что то не понятно, спрашивайте.

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Jsoup parsing

Сообщение Prospekt » 19 июн 2012, 19:41

И что не получается?
Предположим у вас на форме 3 ТехтВиев с соответствующими id "text_1","text_2", "text_3". Как я понял у вас форма фиксирована, т.е. у ней есть 3 элемента (ни 2, ни 4, а именно 3).
Elements содержит список распарсенных участков кода HTML. Как получать этот список вы привели сами.
Теперь чтобы первое значение записалось в "text_1" нужно что-то вроде:

Код: Выделить всё

Elements description;
for(int i=0; (i<description.size())&&(i<3); i++){
 TextView tv = findById("text_"+i);
 Element el = description.get(i);
 tv.setText(el.text);
}
Этой библиотеки под рукой нет, поэтому методы взятие элемента из списка и размера списка могут быть иными. Но в целом должно выглядеть как-то так. Данный код выводит текстовые значения первых трех элементов в соотвествующие TextView-ы.
Как я понимаю, если форма у вас имеет переменную длинну и формируется динамически, то вам придется хранить количество уже имеющихся ТехтВиев-ов на форме. Если это количество совпадает с длинной найденных элементов, то просто заменить у них текстовые значения. Если список длиннее добавить на форму недостающее количество, а если короче удалить лишнии элементы с формы.

Вы же собственно все сами и сделали, поэтому я не понимаю собственно в чем вопрос. В том как получить текст из Element (.text) и вставить его в TextView найденный через id? На каком этапе проблема, и в чем она?

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 20:35

Подробнее о библиотеке можно посмотреть на сайте http://jsoup.org. Сейчас попробую сделать то что ты описал.
А вот как теперь быть:

Код: Выделить всё

Document doc = null;
		try {
            File input = new File("input/FILE.xml");
            doc = Jsoup.parse(input, "UTF-8","http://www.dzone.com/links/?type=html&p=2");
            Elements descriptions = doc.select("div.details > p.description");
       } catch (Exception e) {
            e.printStackTrace();
        }
		
		Elements description;
		for (int i = 0; (i < description.size()) && (i < 3); i++) {
			TextView tv = findViewById("textView" + i);
			Element el = description.get(i);
			tv.setText(el.textView);
		}

Подчеркивает жирный элемент: "tv.setText(el.textView);"
"textView cannot be resolved or is not a field"

Может попробовать реализовать с помощью ListView (вместо textview)? Все таки раз Elements, значит их много (не один), значит выводить в цикле в список.

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Jsoup parsing

Сообщение Prospekt » 19 июн 2012, 20:59

По ходу нужно не
tv.setText(el.textView); (такого поля у этого класса нет)
а
tv.setText(el.text()); если нужно получить текст вместе с вложенными тегами и телом
или tv.setText(el.ownText()); если нужно получить только текст этого элемента
ещё есть метод data() но что он выдает я не знаю.

СТОП!!!!
Я как-то упустил, что элементы выводятся в список. Я почему-то думал в форму, состоящую из ТехтВиев-ов. Или нет? чего-то я запутался.

10-я строка лишняя
Elements description(s); - это я чтобы было понятно, что есть что.
Последний раз редактировалось Prospekt 19 июн 2012, 21:09, всего редактировалось 1 раз.

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 21:04

Я это недавно дописал. Изначально выводятся в textview но может так как элементов много, то стоит попробовать Listview? Вообще в будущем планируется пасить целый список, но я решил начать с легкого и выводить просто в textview

Ругается на "findById" и предлагает создать метод "findViewById". Но зачем его создавать, если там нечего описывать.
Вот код ошибки:
"The method findById(String) is undefined for the type"
Это означает, что метод полезен только для строк?
Убрал "Elements description" теперь пишет "description cannot be resolved"

Кстати вот еще интересно, почему после try {} catch {} типы указанные внутри них снаружи оказываются необъявленными....?

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 21:15

Код: Выделить всё

Document doc = null;
		try {
			doc = Jsoup.connect("http://yandex.ru")
					.get();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String title = doc.title();
		tvInfo.setText(title);
Вот как было раньше. И все он выводил. А с появлением Elements все испортилось...

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Jsoup parsing

Сообщение Prospekt » 19 июн 2012, 21:18

Это я ошибку сделал.
Ругается на "findById" и предлагает создать метод "findViewById
Правильно советует. Я просто код не в IDE писал поэтому и пропустил часть слова.
прибавь к description на конец "s". Поля в 5-й и 10- строке это одно и тоже. Я просто описался. И вообще, внеси код под блок try{...} после 5-й строки.

Счас подожди.

Естественно не видит. Поле объявлено внутри блока будет иметь локальную область видимости, т.е. лоступно только внутри этого же блока. Чтобы сделать поле видимым, надо объявить его до блока, а уже в блоке присваивать значение.

замени на findViewById() я именно это и хотел написать.
Последний раз редактировалось Prospekt 19 июн 2012, 21:24, всего редактировалось 1 раз.

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 21:20

Про description (s) уже исправлял, но когда он был за пределами try... все равно подчеркивал. Сейчас внес внутрь и подчеркивает только findbyid

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 21:27

Заменить строку на это: "TextView tv = findViewById("textView" + i);"?
Теперь ошибка такая: "The method findViewById(int) in the type Activity is not applicable for the arguments (String)"

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Jsoup parsing

Сообщение Prospekt » 19 июн 2012, 21:29

ДА. Здесь мы выбираем тот ТекстВиев которому будем присваивать текст.
Блин, забыл, что кастомизацию (TextView) надо делать, вот оно побочное действие автоматизации.

Да уж. сегодня явно не мой день. Ну конечно, нельзя в аргумент передавать строку. Надо передавать int из R.id

Ладно в кчестве кастыля сделай так:

int[] idtext = new int[]{R.id.textView1 , R.id.textView2 , R.id.textView3 }; (где-нибудь вначале класса)

и

TextView tv = (TextView)findViewById(idtext);
Это конечно не красиво, но для опробывания сойдет.

Кастомизация - это приведение типов (от слова "cast").
Последний раз редактировалось Prospekt 19 июн 2012, 21:37, всего редактировалось 1 раз.

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 21:40

Вот что в итоге получил:

Код: Выделить всё

int[] idtext = new int[]{R.id.textView1 , R.id.textView2 , R.id.textView3 };
		Document doc = null;
		try {
            File input = new File("input/FILE.xml");
            doc = Jsoup.parse(input, "UTF-8","http://www.dzone.com/links/?type=html&p=2");
            Elements descriptions = doc.select("div.details > p.description");
            for (int i = 0; (i < descriptions.size()) && (i < 3); i++) {
            	TextView tv = (TextView)findViewById(idtext[i]);
    			Element el = descriptions.get(i);
    			tv.setText(el.ownText());
    		}
       } catch (Exception e) {
            e.printStackTrace();
        }

Сейчас буду пробовать.
Странно, вывел мне только форму мою, с тремя разными textview. Наверно надо разбираться в коде парсера. Может сайт уже устарел, и его CSS код изменился...
А должен вывести что то вроде этого:
<p class="description">
In administrative systems, there is often a need to import and parse csv files. .NET actually has a built in CSV parser, although it is...&nbsp;
<a href='/links/built_in_net_csv_parser.html'>more&nbsp;&raquo;</a>

</p>"
Последний раз редактировалось Xpert043 19 июн 2012, 21:46, всего редактировалось 1 раз.

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Jsoup parsing

Сообщение Prospekt » 19 июн 2012, 21:45

А ты выведи в Log значение descriptions.size()

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 21:48

Стыдно спрашивать, но: "Log.d(descriptions.size());"...?

Отойду пока, вернусь к этому делу позже. Спасибо за помощь. Об успешном (надеюсь) исходе отпишусь:)

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Jsoup parsing

Сообщение Prospekt » 19 июн 2012, 21:53

Ничего стыдного. Если ты работаешь в Эклипсе, то там наверное надо так
final String LOG_TAG = "myLogs";
Log.d(LOG_TAG, descriptions.size());

Чтобы легко можно было найти по логам\тегу

Xpert043
Сообщения: 34
Зарегистрирован: 12 июн 2012, 20:13

Re: Jsoup parsing

Сообщение Xpert043 » 19 июн 2012, 23:26

Сделал, теперь код вот такой:

Код: Выделить всё

int[] idtext = new int[]{R.id.textView1 , R.id.textView2 , R.id.textView3 };
		Document doc = null;
		try {
            File input = new File("input/FILE.xml");
            doc = Jsoup.parse(input, "UTF-8","http://www.dzone.com/links/?type=html&p=2");
            Elements descriptions = doc.select("div.details > p.description");
            for (int i = 0; (i < descriptions.size()) && (i < 3); i++) {
            	TextView tv = (TextView)findViewById(idtext[i]);
    			Element el = descriptions.get(i);
    			tv.setText(el.ownText());
                                  final String LOG_TAG = "myLogs"; 
                                  Log.d(LOG_TAG, descriptions.size());
    		}
       } catch (Exception e) {
            e.printStackTrace();
        }
Подчеркивает Log.d
Ошибка: "The method d(String, String) in the type Log is not applicable for the arguments (String, int)"

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Jsoup parsing

Сообщение Prospekt » 20 июн 2012, 07:34

Блин,
Замени на
Log.d(LOG_TAG, ""+descriptions.size());
Или более правильный вариант
Log.d(LOG_TAG, Integer.toString( descriptions.size()));

Ответить