Trong bài tutorial Viết chương trình sử dụng Jsoup, chúng ta đã làm quen với các hàm chức năng của Jsoup và viết một chương trình để truy xuất dữ liệu, tổng hợp các đường link và các file ảnh của một trang web bất kỳ. Trong bài tutorial này chúng ta sẽ sử dụng Jsoup để tiến hành tìm kiến trên Google và lọc các dữ liệu trả về.
Để kết nối jsoup với Google search ta cũng sử dụng hàm Jsoup.connect(url).get(). Tuy nhiên ta thiết lập thêm thông số User Agent bằng cách sử dụng hàm .userAgent() (các bạn có thể kiểm tra User Agent của mình bằng cách truy cập trang What is my User Agent? . Trong trường hợp nếu ta không thiết lập User Agent thì Jsoup sẽ sử dụng Java version là giá trị mặc định của User Agent String ).
1 2 3 4 5 |
//Define user agent private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"; // Declare a Document object private static Document document; document = Jsoup.connect(googleQuery).userAgent(USER_AGENT).timeout(5000).get(); |
Trong bài tutorial này, chúng ta sẽ viết hàm googleSearch(String searchKey, int numOfResult, String dateRange, int sort) để thực hiện chức năng tìm kiếm và trả về kết quả của Google. Tương tư như khi ta tìm kiếm thông thường, Google trả về kết quả ứng với từng keyword cụ thể là danh sách các trang web chứa thông tin liên quan đến keyword đó. Ở đây ta sẽ lưu kết quả trả về theo ba trường thông tin:
– Title: là tên của trang web
– Url: là đường link tới trang web
– Summary: là phần tóm tắt nội dung mà Google hiện thị trong kết quả trả về.
Để thuận tiện cho việc truy xuất các trường thông tin này, ta sẽ tạo một SearchResult Class mà mỗi SearchResult object lưu trữ thông tin của một trang web trong kết quả Google trả về.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class SearchResult{ private String title, url,summary; public SearchResult(String title, String url, String summary) { this.title=title; this.url=url; this.summary=summary; } public String getTitle() { return title; } public String getUrl() { return url; } public String getSummary() { return summary; } } |
Hàm googleSearch() ở trên có bốn tham số đầu vào là:
– searchKey: là keyword mà ta cần tìm kiếm thông tin liên quan
– numOfResult: là số lượng kết quả mà Google sẽ trả về
– sort: sắp xếp kết quả trả về theo thứ tự thời gian (sort =1) hoặc theo mức độ liên quan (sort=0)
– dateRange: là khoảng thời gian mà ta muốn thu hẹp phạm vi tìm kiếm. Ở đây ta sử dụng tham số thời gian tbs như sau:
Value | Result |
tbs=qdr:s | Past second |
tbs=qdr:n | Past minute |
tbs=qdr:h | Past hour |
tbs=qdr:h10 | Past 10 hours |
tbs=qdr:d | Past day |
tbs=qdr:w | Past week |
tbs=qdr:m | Past month |
tbs=qdr:y | Past year |
tbs=cdr:1,cd_min:12/8/2016,cd_max:6/5/2018 | From Dec 8,2016 to Jun 5,2018 |
tbs=qdr:a | Anytime |
tbs=sbd:1 | Sort by date |
tbs=sbd:0 | Sort by relevance |
tbs=sbd:1,qdr:m | Past month and Sort by date |
tbs=sbd:0,qdr:m | Past month and Sort by relevance |
Để bóc tách và lưu kết quả theo 3 trường thông tin, ta thực hiện tương tự như trong bài tutorial Viết chương trình sử dụng Jsoup. Với search keyword là BigData, ta thấy các kết quả đều nằm trong class=”g”.
Trong “g” class này thì title của trang web nằm trong thẻ “h3”, còn url nằm trong thẻ “a” với attribute là “href” và nội dung tóm tắt của trang Web nằm trong “st” class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
private static ArrayList<SearchResult> googleSearch(String searchKey,int numOfResult, String dateRange, int sort) { //Construct the search query String googleQuery="https://google.com/search?q="+searchKey+"&num="+numOfResult+"&tbs=qdr:"+dateRange+",sbd:"+sort; //Print out the search query System.out.println("\nThe query string: "+ googleQuery); //An ArrayList to store the search results ArrayList<SearchResult> results=new ArrayList<SearchResult>(); try { document = Jsoup.connect(googleQuery).userAgent(USER_AGENT).timeout(5000).get(); //Traverse the results for (Element result : document.getElementsByClass("g")){ //Extract the title, url and summary of each result String title = result.getElementsByTag("h3").text(); String url = result.getElementsByTag("a").attr("href"); String summary = result.getElementsByClass("st").text(); //Add each result to the ArrayList results.add(new SearchResult(title,url,summary)); } } catch (IOException e) { e.printStackTrace(); } return results; } |
Ngoài hàm googleSearch(String searchKey,int numOfResult, String dateRange, int sort) ở trên, ta tạo thêm hai hàm là googleSearch(String searchKey) và googleSearch(String searchKey,int numOfResult) để cho phép người dùng chỉ cần điền tham số đầu vào là searchKey hoặc (searchKey, numOfResult) (Lưu ý: đối với các ngôn ngữ khác hỗ trợ việc thiết lập giá trị mặc định của tham số đầu vào như Scala, C++ thì ta chỉ cần tạo một hàm duy nhất rồi thiết lập giá trị mặc định. Ví dụ như: googleSearch(String searchKey,int numOfResult=10, String dateRange=”a”, int sort=0). Tuy nhiên do Java không hỗ trợ việc thiết lập giá trị mặc định này nên ta sử dụng phương pháp Overloaded method.)
1 2 3 4 5 6 7 8 9 |
private static ArrayList<SearchResult> googleSearch(String searchKey,int numOfResult) { return googleSearch(searchKey,numOfResult,"a",0); } private static ArrayList<SearchResult> googleSearch(String searchKey) { return googleSearch(searchKey,10,"a",0); } |
Ta sử dụng các hàm googleSearch() để chạy thử một số tìm kiếm với keyword là “Big data” như sau:
– Hiện thị 5 kết quả trong 1 tuần vừa qua và sắp xếp kết quả theo thứ tự liên quan:
1 2 3 4 5 6 7 8 9 |
//Search the key word "Web scraping" for the past 24 hours. Show the most 5 relevance results ArrayList<SearchResult> searchResults= googleSearch("Big data",5,"w",0); System.out.println("\nThe most 5 relevance results: "); for(SearchResult sr:searchResults) { System.out.println("\nThe title: "+sr.getTitle()); System.out.println("The url: "+sr.getUrl()); System.out.println("Summary: "+sr.getSummary()); } |
– Hiện thị 5 kết quả trong 1 tuần vừa qua và sắp xếp kết quả theo thứ tự thời gian ( kết quả trong trường hợp này sẽ khác với kết quả ở trên dù ta cùng sử dụng chung keyword=”Big data” ):
1 2 3 4 5 6 7 8 9 |
//Search the key word "Web scraping" for the past 24 hours. Show the most 5 recent results searchResults= googleSearch("Big data",5,"w",1); System.out.println("\nThe most 5 recent results: "); for(SearchResult sr:searchResults) { System.out.println("\nThe title: "+sr.getTitle()); System.out.println("The url: "+sr.getUrl()); System.out.println("Summary: "+sr.getSummary()); } |
– Sử dụng googleSearch(String searchKey,int numOfResult) để hiện thị top 5 kết quả (không giới hạn thời gian)
– Sử dụng googleSearch(String searchKey) để hiện thị các kết quả tìm kiếm với mặc định số lượng kết quả là 10.
Như vậy ta đã hoàn thành chương trình sử dụng Jsoup để tiến hành tìm kiếm trên Google và thiết lập các tham số khác nhau để tìm được kết quả mong muốn. Các bạn có thể tham khảo full code của chương trình dưới đây:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import java.io.IOException; import java.util.ArrayList; //Object to store search result class SearchResult{ private String title, url,summary; public SearchResult(String title, String url, String summary) { this.title=title; this.url=url; this.summary=summary; } public String getTitle() { return title; } public String getUrl() { return url; } public String getSummary() { return summary; } } public class GoogleSearchJsoup { //Define user agent private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"; // Declare a Document object private static Document document; public static void main(String[] args) { //Search the key word "Web scraping" for the past 24 hours. Show the most 5 relevance results ArrayList<SearchResult> searchResults= googleSearch("Big data",5,"w",0); System.out.println("\nThe most 5 relevance results: "); for(SearchResult sr:searchResults) { System.out.println("\nThe title: "+sr.getTitle()); System.out.println("The url: "+sr.getUrl()); System.out.println("Summary: "+sr.getSummary()); } //Search the key word "Web scraping" for the past 24 hours. Show the most 5 recent results searchResults= googleSearch("Big data",5,"w",1); System.out.println("\nThe most 5 recent results: "); for(SearchResult sr:searchResults) { System.out.println("\nThe title: "+sr.getTitle()); System.out.println("The url: "+sr.getUrl()); System.out.println("Summary: "+sr.getSummary()); } //Search the key word "Web scraping" for all time. Show the top 5 results searchResults= googleSearch("Big data",5); System.out.println("\nThe top 5 results of all time: "); for(SearchResult sr:searchResults) { System.out.println("The title: "+sr.getTitle()); } //Search the key word "Web scraping" for all time. Show the default results searchResults= googleSearch("Big data"); System.out.println("\nThe default 10 results of all time: "); for(SearchResult sr:searchResults) { System.out.println("The title: "+sr.getTitle()); } } /** * Get the result from google search * @param searchKey The keywords for searching * @param numOfResult The number of results need to be displayed * @param dateRange The date range of the result * @param sort 0:sort by relevance, 1: sort by date * @return */ private static ArrayList<SearchResult> googleSearch(String searchKey,int numOfResult, String dateRange, int sort) { //Construct the search query String googleQuery="https://google.com/search?q="+searchKey+"&num="+numOfResult+"&tbs=qdr:"+dateRange+",sbd:"+sort; //Print out the search query System.out.println("\nThe query string: "+ googleQuery); //An ArrayList to store the search results ArrayList<SearchResult> results=new ArrayList<SearchResult>(); try { document = Jsoup.connect(googleQuery).userAgent(USER_AGENT).timeout(5000).get(); //Traverse the results for (Element result : document.getElementsByClass("g")){ //Extract the title, url and summary of each result String title = result.getElementsByTag("h3").text(); String url = result.getElementsByTag("a").attr("href"); String summary = result.getElementsByClass("st").text(); //Add each result to the ArrayList results.add(new SearchResult(title,url,summary)); } } catch (IOException e) { e.printStackTrace(); } return results; } //Use this method if we dont need to specify the date range and sort order //(Since java doesnt support default value so we use the overloaded approach) private static ArrayList<SearchResult> googleSearch(String searchKey,int numOfResult) { return googleSearch(searchKey,numOfResult,"a",0); } private static ArrayList<SearchResult> googleSearch(String searchKey) { return googleSearch(searchKey,10,"a",0); } } |