【问题标题】:Parsing with Jsoup in arraylist在arraylist中使用Jsoup解析
【发布时间】:2015-04-12 07:41:03
【问题描述】:

我如何用 jsoup 解析这个?

    <!-- NOVINEEE -->
<div class="right_naslov"><a href="/e-novine">e-novine</a></div>

  <div class="right_post">
    <span class="right_post_nadnaslov"><font class="nadnaslov">Zanimljiv zadatak</font></span><span class="right_post_datum"><font class="datum">12.12.2014.</font></span>
    <span class="right_post_naslov_v"><font class="naslov"><a href="/e-novine/n/?id=340">Profesor učenicima zadao najbolji zadatak ikad!</a></font></span>
    <span class="right_post_podnaslov"><font class="podnaslov"></font></span>
    <div class="right_post_tekst"><a href="/e-novine/n/?id=340"><img width="180" align="left" class="novine_slika_thumbm" border="0" src="/fajlovi/slike/thumbm/4161-zadatak_naslovna.jpg" /></a><p>72-godi&scaron;nji profesor biv&scaron;im učenicima iz godine u godinu &scaron;alje pisma &scaron;to nije lak zadatak jer mnogi ne žive u istoj državi. Iako radi ne&scaron;to stvarno posebno, Bruce sebe i dalje smatra prosječnim profesorom. Učenici ipak smatraju suprotno...</p>
<div>&nbsp;</div></div>
    </div>
</div>

我想获取right_naslov的内容,以及nadnaslov、naslov的字体类,以及right_post_tekst的img src和a href。

我试着做这样的事情:

Document doc = Jsoup.connect(url).get();
            Elements post = doc.select("right_naslov right_post nadnaslov");
            HashMap<String, String> map = new HashMap<String, String>();

            map.put("rank", post.text());
            // Get the second td
            map.put("country", post.text());
            // Get the third td
            map.put("population", post.text());

            // Set all extracted Jsoup Elements into the array
            arraylist.add(map);

然后我会这样做:

resultp = data.get(position);

// Locate the TextViews in listview_item.xml
rank = (TextView) itemView.findViewById(R.id.rank);
country = (TextView) itemView.findViewById(R.id.country);
population = (TextView) itemView.findViewById(R.id.population);


// Capture position and set results to the TextViews
rank.setText(resultp.get(PocetnaFragment.RANK));
country.setText(resultp.get(PocetnaFragment.COUNTRY));
population.setText(resultp.get(PocetnaFragment.POPULATION));

我一直在关注这个教程:http://www.androidbegin.com/tutorial/android-jsoup-listview-images-texts-html-tables-tutorial/

有多个right_posts

谢谢


更新

在位于下方的答案后出现以下错误(在所有 cmets 之后):

02-14 23:50:17.490    2469-2530/gimbi.edu.ba W/System.err﹕ java.lang.NullPointerException: Attempt to invoke virtual method 'org.jsoup.select.Elements org.jsoup.nodes.Element.select(java.lang.String)' on a null object reference
02-14 23:50:17.494    2469-2530/gimbi.edu.ba W/System.err﹕ at gimbi.edu.ba.PocetnaFragment$JsoupListView.doInBackground(PocetnaFragment.java:147)
02-14 23:50:17.494    2469-2530/gimbi.edu.ba W/System.err﹕ at gimbi.edu.ba.PocetnaFragment$JsoupListView.doInBackground(PocetnaFragment.java:103)
02-14 23:50:17.494    2469-2530/gimbi.edu.ba W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
02-14 23:50:17.494    2469-2530/gimbi.edu.ba W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
02-14 23:50:17.494    2469-2530/gimbi.edu.ba W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
02-14 23:50:17.494    2469-2530/gimbi.edu.ba W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
02-14 23:50:17.494    2469-2530/gimbi.edu.ba W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
02-14 23:50:17.494    2469-2530/gimbi.edu.ba W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
02-14 23:50:46.713    2469-4859/gimbi.edu.ba W/System.err﹕ java.lang.NullPointerException: Attempt to invoke virtual method 'org.jsoup.select.Elements org.jsoup.nodes.Element.select(java.lang.String)' on a null object reference
02-14 23:50:46.718    2469-4859/gimbi.edu.ba W/System.err﹕ at gimbi.edu.ba.PocetnaFragment$JsoupListView.doInBackground(PocetnaFragment.java:147)
02-14 23:50:46.718    2469-4859/gimbi.edu.ba W/System.err﹕ at gimbi.edu.ba.PocetnaFragment$JsoupListView.doInBackground(PocetnaFragment.java:103)
02-14 23:50:46.719    2469-4859/gimbi.edu.ba W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
02-14 23:50:46.719    2469-4859/gimbi.edu.ba W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
02-14 23:50:46.719    2469-4859/gimbi.edu.ba W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
02-14 23:50:46.719    2469-4859/gimbi.edu.ba W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
02-14 23:50:46.719    2469-4859/gimbi.edu.ba W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
02-14 23:50:46.719    2469-4859/gimbi.edu.ba W/System.err﹕ at java.lang.Thread.run(Thread.java:818)

正如我在下面所说的,我尝试删除 img element,但是当我调用 map.put 方法时,所有元素都是一样的。

【问题讨论】:

    标签: android xml html-parsing jsoup


    【解决方案1】:

    阅读link,了解如何使用 Jsoup 提取数据。

    以下是我根据您的场景的示例。

        Document doc = null;
        Element aEle = null;
        Element fontEle = null;
    
        try {
            doc = ......
    
            /** Get A tag that is under DIV with classname right_naslov **/
            aEle = doc.select("div.right_naslov > a").first();
            if (aEle != null) {
                System.out.println("right_naslov content: " + aEle.ownText());
            }
    
            /** Get Font tag with [classname=nadnaslov] under span[classname=right_post_nadnaslov] under div[lassname=right_post]  **/
            /** Try to get Font[classname=naslov] with the following method **/
            fontEle = doc.select("div.right_post > span.right_post_nadnaslov > font.nadnaslov").first();
            if (fontEle != null) {
                System.out.println("font nadnaslov content: " + fontEle.ownText());
            }
    
            /** Get A tag that is under div[classname=right_post_tekst] under div[classname=right_post] **/
            aEle = doc.select("div.right_post > div.right_post_tekst > a").first();
            if (aEle != null) {
                System.out.println("a href: " + aEle.attr("href"));
    
                /** Get inner IMG tag with classname as 'novine_slika_thumbm' **/
                Element imgEle = aEle.select("img.novine_slika_thumbm").first();
                if (imgEle != null) {
                    System.out.println("img src: " + imgEle.attr("src"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    

    上述示例仅在您正在解析的 HTML 文档中只有一个 DIV[classname=right_naslov]DIV[classname=right_post] 时才有效,因为我使用 Elements.first() 提取数据,这意味着我总是选择符合我们提取的第一个元素标准。尝试玩 Jsoup,玩得开心。获得所有数据后,将它们存储在HashmapArrayList 中。


    更新

    你可以做的是用Document.select() 选择多个DIV[classname=right_post],它会返回Elements 对象。然后循环每个Element 以获取其内部数据。在下面的示例中,您将在 arraylist 变量中获得两个 HashMap 项目。

    2 div[classname=right_naslov] 我只检索&lt;!-- NOVINEEE --&gt; 评论部分之后的第二个。有 5 div[classname=right_post],我已经忽略了那些没有内部元素 span[classname=right_post_nadnaslov] 的。

        List<HashMap<String, String>> arraylist = new ArrayList<HashMap<String, String>>();
        Elements aEles = null;
        Elements divRightPostEles = null;
        String rightNaslov = null;
        Document doc = null;
    
        try {
            doc = Jsoup.connect(url).get();
    
            /** Get A tag that is under DIV with classname right_naslov **/
            aEles = doc.select("div.right_naslov > a");
            if (aEles != null && aEles.size() > 0) {
                if (aEles.size() == 2)
                    rightNaslov = aEles.get(1).ownText();
                else
                    rightNaslov = aEles.first().ownText();
            }
    
            /**
             * Since you say there are multiple DIV with right_post as
             * classname, we will get all those right post elements and loop
             * them one by one to retrieve its inner elements
             **/
            divRightPostEles = doc.select("div.right_post");
    
            for (Element rightPostDiv : divRightPostEles) {
                /** Each loop of this represents a right_post DIV element **/
    
                HashMap<String, String> map = new HashMap<String, String>();
    
                /**
                 * Get Font tag with [classname=nadnaslov] under
                 * span[classname=right_post_nadnaslov] under
                 * div[lassname=right_post]
                 **/
                /** Try to get Font[classname=naslov] with the following method **/
                Elements fontNadnaslov = rightPostDiv
                        .select("span.right_post_nadnaslov > font.nadnaslov");
    
                /**
                 * Get A tag that is under div[classname=right_post_tekst] under
                 * div[classname=right_post]
                 **/
                Element aRightPostTekst = rightPostDiv.select(
                        "div.right_post_tekst > a[href]").first();
    
                // Retrive Jsoup Elements
                if (fontNadnaslov != null && fontNadnaslov.size() > 0) {
                    map.put("country", fontNadnaslov.first().ownText());
    
                    if (aRightPostTekst != null) {
                        map.put("population", aRightPostTekst.attr("href"));
    
                        Element img = aRightPostTekst.select("img[src]").first();
    
                        if (img != null)
                            map.put("image", img.attr("src"));
                    }
    
                    if (rightNaslov != null)
                        map.put("rank", rightNaslov);
                    // Set all extracted Jsoup Elements into the array
                    arraylist.add(map);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    

    【讨论】:

    • 类名右帖有多个div。我尝试将它包装在一个 for 函数中,它作为两个单独的列表视图项返回,但它得到了所有可能的 right_post_nadnaslov,并且只有一个 a href (aEle)。我怎样才能让它们看起来分开?这是我尝试做的:pastebin.com/ZZse378K
    • 我替换了 input and doc.output because 我无法导入任何内容,我将其替换为 Document doc = Jsoup.connect(url).get(); 我收到以下错误:pastebin.com/6DH8iCxV,它引用了我的 ListViewAdapter(以下几行):@Override public int getCount() { return data.size(); },这是我的 ListViewAdapter.java:pastebin.com/cZtsrDpL
    • 我不太擅长 Android,但我会尽力提供帮助。用一个值初始化 ListViewAdapter 中的数据。 ArrayList> data = null;或 ArrayList> data = new ArrayList>();
    • 我用arraylist = new ArrayList&lt;HashMap&lt;String, String&gt;&gt;();而不是List&lt;HashMap&lt;String, String&gt;&gt; arraylist = new ArrayList&lt;HashMap&lt;String, String&gt;&gt;();,还删除了那些system.out.println(删除了函数的最后一个),我没有收到任何错误,但它是空白的,就像它没有'不返回任何数据。
    • 收到以下警告:pastebin.com/aicUBvYJ,我尝试删除 img 元素,但 map.put 中的每个元素都相同
    猜你喜欢
    • 1970-01-01
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 2014-07-30
    • 2012-11-06
    • 1970-01-01
    相关资源
    最近更新 更多