当前位置: 首页 > 知识库问答 >
问题:

Jsoup解析Java中动态加载网页

阎单鹗
2023-03-14
import java.io.IOException;
import java.util.ArrayList;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;


public class listGrabber {
    public static void main(String[]args) {
        try {
            Document doc = Jsoup.connect("https://play.google.com/store/apps/category/GAME_ACTION/collection/topselling_free").get();
            int count = 0;
            Elements elements;
            String url;
            ArrayList<String> list = new ArrayList<>();
            do{
                elements = doc.select("a[class^=title]").get(count).select("a[class^=title]");

                url = "";
                url = elements.attr("abs:title").replaceAll("https://play.google.com/store/apps/category/GAME_ACTION/collection/","");
                url = url.replaceAll("®|™","");
                url = url.replaceAll("[(](.*)[)]","");
                list.add(url);
                System.out.println(url);
                count++;
            }while (url!="" &&url!=null);
            // String divContents =
            // doc.select(".id-app-orig-desc").first().text();
            // elements.remove("div");
        } catch (IOException e) {

        }
    }
}

正如你在上面看到的,我正试图从https://play . Google . com/store/apps/category/GAME _ ACTION/collection/top selling _ free中抓取一个单词列表

谷歌Play商店页面加载更多的元素,每次你滚动到页面的底部。

我的程序将抓取显示的前40个元素,但由于j汤不会加载动态加载的网页的其余部分,因此我无法抓取前40个元素之外的任何元素。

此外,如果你在页面上滚动到游戏#300,会出现一个Show More按钮,我还想解析Show More按钮之外的元素。

Jsoup 有没有办法解析所有动态加载到页面上的元素?

共有1个答案

阎乐池
2023-03-14

编辑-在OP的几句评论之后,我完全理解了他想要实现的目标。我对原来的解决方案做了一些修改并进行了测试

您可以使用< code>JSOUP来完成。在第一页之后,获取下一页需要发送一个带有一些头的< code>post请求。标题包含(除了别的以外)起始编号和要获取多少条记录。如果您发送一个illegel数字(即,您询问包含游戏编号700的页面,但结果只包含600个游戏),您将再次获得第一页。您可以循环浏览页面,直到得到您已经得到的结果。< br >有时服务器返回600个结果,有时只有540个,我不知道为什么。< br >代码是-

import java.util.regex.Pattern;
import org.jsoup.Connection;
import org.jsoup.Connection.Method;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

public class HelloWorld {

public static void main(String[] args) {

    Connection.Response res = null;
    Document doc = null;
    Boolean OK = true;
    int start = 0;
    String query;
    ArrayList<String> tempList = new ArrayList<>();
    ArrayList<String> games = new ArrayList<>();
    Pattern r = Pattern.compile("title=\"(.*)\" a");

    try {   //first connection with GET request
        res = Jsoup.connect("https://play.google.com/store/apps/category/GAME_ACTION/collection/topselling_free")
                .method(Method.GET)
                .execute(); 
        doc = res.parse();
    } catch (Exception ex) {
        //Do some exception handling here
    }
    for (int i=1; i <= 60; i++) {    //parse the result and add it to the list
        query = "div.card:nth-child(" + i + ") > div:nth-child(1) > div:nth-child(3) > h2:nth-child(2) > a:nth-child(1)";
        tempList.add(doc.select(query).toString());
    }

    while (OK) {    //loop until you get the same results again
        start += 60;    
        System.out.println("now at number " + start);
        try {      //send post request for each new page
            doc = Jsoup.connect("https://play.google.com/store/apps/category/GAME_ACTION/collection/topselling_free?authuser=0")
                    .cookies(res.cookies())
                    .data("start", String.valueOf(start))
                    .data("num", "60")
                    .data("numChildren", "0") 
                    .data("ipf", "1")
                    .data("xhr", "1")
                    .post();
        } catch (Exception ex) {
            //Do some exception handling here
        }
        for (int i=1; i <= 60; i++) {    //parse the result and add it to the list
            query = "div.card:nth-child(" + i + ") > div:nth-child(1) > div:nth-child(3) > h2:nth-child(2) > a:nth-child(1)";
            if (!tempList.contains(doc.select(query).toString())) {
                tempList.add(doc.select(query).toString());
            } else {    //we've seen these games before, time to quit
                OK = false;
                break;
            }               
        }   
    }
    for (int i = 0; i < tempList.size(); i++) {    //remove all redundent info.
        Matcher m = r.matcher(tempList.get(i));
        if (m.find()) {
            games.add(m.group(1));
            System.out.println((i + 1) + " " + games.get(i));
        }           
    }
}
}

代码可以进一步改进(例如使用单独的方法处理所有列表),因此由您决定。
我希望这能为你工作。

 类似资料:
  • 我正在做一个项目,通过使用JSOUP解析一个网站来显示歌曲名称和指向该歌曲的链接。唯一的问题是,我只能得到前10个元素,我想从那个网站,因为当你向下滚动,网站生成更多的元素。我试图解析的特定网站是一个名为Trappedio的音乐网站。你在查看网站时会注意到,当你向下滚动时,会出现更多的歌曲名称和图像。当我在chrome中使用inspect元素时,我看到当我滚动时,它生成了更多我试图解析的元素。 我

  • 问题内容: 分析这个问题后,我发现了有关在Linux 上动态加载()上下文中弱符号解析行为的一些信息。现在,我正在寻找管理该规范的规范。 让我们举个例子。假设有一个程序可以按此顺序动态加载库和。如果依赖于其他两个库(实际上在该示例中)和(实际上),则通常使用导出的符号可以满足中的弱符号链接。但是如果还依赖但不依赖,那么这些弱符号显然不会被联系起来。它好像inkages只能看从符号和及其所有的依赖关

  • 问题内容: 我查找了语法并搜索了api,但仍然对该过程感到困惑。我还搜索了Stackoverflow。加载类并从中动态创建对象的正确方法是什么?换句话说,我希望用户指定要创建的对象类型,然后创建该类型的对象。我不需要菜单,因为我希望他们能够选择当前目录中的任何类。 问题答案: 假设该类具有无参数构造函数,则最简单的方法是- 参考-java.lang.Class

  • 我在寻找一个简单的解决方案。 我有一个xml文件: 我想做一个动态解析器。 我知道我可以用org.w3c.dom.*读取xml,org.w3c.dom.Node.getTextContent()我可以得到标签的值。 有什么建议吗? [编辑]通过反思: 变量“clazz”是java.lang.类,对吗?我怎么能转换文本内容值(在字符串)到任何包装类型? valueOf可能是我可以使用反射调用的通用方

  • 我试图在这里使用JSOUP解析html标记。我对jsoup是新来的。基本上,我需要解析这些标记,获取这些标记中的文本,并应用class属性中提到的样式。 我正在创建一个SpannableStringBuilder,它可以创建子字符串,应用样式,并将它们附加到没有样式的文本中。 我不确定如何解析不在任何标记之间的字符串,例如“there are”和“worker from the”。 需要输出,例如