2016-12-11 6 views
0

jSoupを使用してページをスクラップすると、ページ上のすべてのリンクを集めることができます。jSoupの[Elements from Duplicate URLs]リストから[Remove URLs]を削除しますか?

Elements allLinksOnPage = doc.select("a"); 

どれが素晴らしいですか。今、このリストから重複したURLを削除するにはどうすればよいでしょうか?私。両方のメインナビゲーションでリンクされている/contact-us.htmlを想像してみてください。

すべての重複したURLが削除されたら、次のステップは、その一意のURLをクロールしてループを継続することです。

これの実用性についての質問。コードの場合。ページ-2.htmlがクロールされたときに

for (Element e : allLinksOnPage) { 
    String absUrl = e.absUrl("href"); 

    //Asbolute URL Starts with HTTP or HTTPS to make sure it isn't a mailto: link 
    if (absUrl.startsWith("http") || absUrl.startsWith("https")) { 
     //Check that the URL starts with the original domain name 
     if (absUrl.startsWith(getURL)) { 
      //Remove Duplicate URLs 
      //Not sure how to do this bit yet? 
      //Add New URLs found on Page to 'allLinksOnPage' to allow this 
      //For Loop to continue until the entire website has been scraped 
     } 
    } 
} 

だから、質問されると、ループの最後の部分、想像し、より多くのURLはここに特定し、allLinksOnPage変数に追加されます。

for-loopは、完全なリストの長さ、つまりpage-1.htmlに10個のリンクがあり、page-2.htmlに10個のリンクが続くので、20ページが合計でクロールされます。ループは識別された最初の10個のリンクの長さ、すなわち 'for(Element e:allLinksOnPage)'のコードがトリガーされるまでの間だけ継続しますか?

これはロジックが確定した後は必然的にデータベースになりますが、最初はロジックを純粋にJavaベースにして、DBへの読み書きをたくさん防ぎます。

+0

セットを使用してURLを保存し、すでに処理されている場合はすべてのURLをチェックできます。 btw 'absUrl.startsWith(" http ")|| absUrl.startsWith( "https") 'は冗長です。 'startswith(" https ")の部分を削除することができます –

+0

ありがとう@MadMattsはい正しいです –

答えて

1

は1回だけ繰り返されます。リンクを発見したページに関する情報は一切取得しません。

ただし、これにはSetListを使用できます。さらに、URLクラスを使用して、プロトコルを抽出することができます。

URL startUrl = ...; 
Set<String> addedPages = new HashSet<>(); 
List<URL> urls = new ArrayList<>(); 
addedPages.add(startUrl.toExternalForm()); 
urls.add(startUrl); 
while (!urls.isEmpty()) { 
    // retrieve url not yet crawled 
    URL url = urls.remove(urls.size()-1); 

    Document doc = JSoup.parse(url, TIMEOUT); 
    Elements allLinksOnPage = doc.select("a"); 
    for (Element e : allLinksOnPage) { 
     // add hrefs 
     URL absUrl = new URL(e.absUrl("href")); 

     switch (absUrl.getProtocol()) { 
      case "https": 
      case "http": 
       if (absUrl.toExternalForm().startsWith(getURL) && addedPages.add(absUrl.toExternalForm())) { 
        // add url, if not already added 
        urls.add(absUrl); 
       } 
     } 
    } 
} 
+0

これは完璧です、ありがとうございます@ fabian。これはさまざまなサイトでこれをテストしており、多くのサイトにリンクがあることに気付きましたその中に#が付いているURLには同じURLが重複していますが、この質問の範囲外であるため、URLを完全に正規化する方法については新しい質問を開きます。 –

関連する問題