【问题标题】:How to filter out certain links using Jsoup如何使用 Jsoup 过滤掉某些链接
【发布时间】:2021-06-14 09:56:28
【问题描述】:

我正在创建一个简单的程序,它接受用户的搜索输入和他们想要接收的链接数量。但是,我的代码有 2 个问题。

  1. 当我打印出链接时,它还包括图片、新闻等的链接...我想知道如何才能只保留与搜索相关的链接。

     String searchURL = GOOGLE_SEARCH_URL + "?q="+searchTerm+"&num="+num;
     Document doc = Jsoup.connect(searchURL).userAgent("Mozilla/5.0").get();     
     Elements results = doc.select("a[href]");
    

    但是,使用a[href] 过滤文档会包括页面上的所有链接。我还尝试使用h3.r > a,它根本没有返回任何结果,还有a > h3,它解决了我当前的问题,但它只会显示标题而不是实际链接。这是我想摆脱的输出的一部分:

Title: Google
Link: https://www.google.com/?sa=X&ved=0ahUKEwifoOa-p7bvAhUDqlkKHS8fCsIQOwgC

Title: Google
Link: https://www.google.com/?num=5&output=search&sa=X&ved=0ahUKEwifoOa-p7bvAhUDqlkKHS8fCsIQPAgE

Title: News
Link: https://www.google.com/search?q=java&num=5&source=lnms&tbm=nws&sa=X&ved=0ahUKEwifoOa-p7bvAhUDqlkKHS8fCsIQ_AUICCgB

Title: Images
Link: https://www.google.com/search?q=java&num=5&source=lnms&tbm=isch&sa=X&ved=0ahUKEwifoOa-p7bvAhUDqlkKHS8fCsIQ_AUICSgC

Title: Books
Link: https://www.google.com/search?q=java&num=5&source=lnms&tbm=bks&sa=X&ved=0ahUKEwifoOa-p7bvAhUDqlkKHS8fCsIQ_AUICigD

Title: Maps
Link: https://maps.google.com/maps?q=java&num=5&um=1&ie=UTF-8&sa=X&ved=0ahUKEwifoOa-p7bvAhUDqlkKHS8fCsIQ_AUICygE

Title: Videos
Link: https://www.google.com/search?q=java&num=5&source=lnms&tbm=vid&sa=X&ved=0ahUKEwifoOa-p7bvAhUDqlkKHS8fCsIQ_AUIDCgF
...
  1. 因此,我最终得到的链接比请求的数量多得多,而且我认为它还包括页面的子链接(例如:当您搜索 Java 时,第一个链接是 java.com,及其子链接,是下载页面)。

简而言之,我希望能够过滤掉 google 链接,例如图片、新闻、地图、购物等……并且只包括页面的主要链接。

【问题讨论】:

    标签: java css text filter jsoup


    【解决方案1】:

    jsoup 无法实现您的目标,因为 Google 返回的 HTML 内容不包含搜索结果。一切都是从 JavaScript 构建的。您可以通过运行来检查它:

    curl https://www.google.com/\?q\=stackoverflow\&num\=3 | grep stackoverflow
    

    您将找不到任何 stackoverflow URL。您可以尝试自己运行 JavaScript,但使用 Google Programmable Search Engine 会更容易。

    【讨论】:

    • 感谢您的帮助。我最终做的是创建两个文档。第一个使用 a > h3 的过滤器来获取标题,另一个是 a[href] 来获取所有标题及其各自的链接。然后我将第二个文档中的所有信息放入一个哈希图中,然后我使用第一个文档中的标题并检查哈希图中的键是否包含我的标题,并使用该值来获取其各自的链接。可能不是最有效的解决方案,但它对我有用。
    【解决方案2】:

    我自己的解决方案:

            Elements title = doc.select("a > h3");
            Elements links = doc.select("a[href]");
            
            Map<String, String> combo = new HashMap<>();
    
            for (Element result : links) {
                combo.put(result.text(),result.attr("abs:href"));
            }
            for (Element result : title) {
                System.out.println("Title:"+result.text());
                String temp = getSimilar(combo, result.text());
                if(temp!=null)
                    System.out.println("Link:"+temp.substring(temp.indexOf("http", temp.indexOf("http") + 1),temp.indexOf("&")));
                else
                    System.out.println("No link found");
                System.out.println();
            }
            
        }
    
        public static String getSimilar(Map<String, String> combo, String sim){
            for (Map.Entry<String,String> key : combo.entrySet()){
                if(key.getKey().contains(sim))
                    return key.getValue();
            }
            return null;
        }
    

    【讨论】:

    • 唯一的问题仍然是,链接的数量总是略有偏差。
    • 获得链接后,您可以随时将它们存储在集合中,例如List&lt;&gt;,而不是直接打印出来;然后过滤集合以排除某些类型的链接(图像,就像你提到的?)并限制输出的总数。
    • 是的,我也想过这样做,但是我想过滤掉很多不同的东西,所以我坚持使用这种方法。为了解决这个问题,当我问用户他们想要多少链接时,我将这个数字乘以 2(因为我得到的链接总是比我要求的少),这导致我得到了一些额外的链接,而不是下,所以我只是在第二个循环结束时手动跳出。
    猜你喜欢
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 2011-06-21
    • 2017-01-28
    • 1970-01-01
    • 2022-11-13
    相关资源
    最近更新 更多