jsoup+htmlUnit能夠實現抓取執行過js的html頁面

1:背景

  原本想用jsoup去抓取一個頁面可是抓取的數據老是不全,而後發現有的數據是頁面執行過js以後渲染到頁面上的,也就是說只有執行過js以後數據頁面上纔會顯示數據,可是jsoup並不能實現執行頁面的js。html

 

2:解決

  搜索後發現htmlunit網絡工具能夠實現執行js,他是一個至關於一個沒有頁面的瀏覽器,解決方案就是先使用htmlUnit發送網絡請求,執行js獲取頁面而後利用jsoup再轉換爲Document頁面對象,而後使用jsoup分析頁面讀取數據。瀏覽器

 

3:htmlUnit發送請求

 1 public static Document getDocument() throws IOException, InterruptedException{
 2         /*String url="https://www.marklines.com/cn/vehicle_sales/search_country/search/?searchID=587200";
 3         Connection connect = Jsoup.connect(url).userAgent("")
 4                 .header("Cookie", "PLAY_LANG=cn; _plh=b9289d0a863a8fc9c79fb938f15372f7731d13fb; PLATFORM_SESSION=39034d07000717c664134556ad39869771aabc04-_ldi=520275&_lsh=8cf91cdbcbbb255adff5cba6061f561b642f5157&csrfToken=209f20c8473bc0518413c226f898ff79cd69c3ff-1539926671235-b853a6a63c77dd8fcc364a58&_lpt=%2Fcn%2Fvehicle_sales%2Fsearch&_lsi=1646321; _ga=GA1.2.2146952143.1539926675; _gid=GA1.2.1032787565.1539926675; _plh_notime=8cf91cdbcbbb255adff5cba6061f561b642f5157")
 5                 .timeout(360000000);
 6         Document document = connect.get();*/
 7         WebClient wc = new WebClient(BrowserVersion.CHROME);
 8         //是否使用不安全的SSL
 9         wc.getOptions().setUseInsecureSSL(true);
10         //啓用JS解釋器,默認爲true
11         wc.getOptions().setJavaScriptEnabled(true);
12         //禁用CSS
13         wc.getOptions().setCssEnabled(false);
14         //js運行錯誤時,是否拋出異常
15         wc.getOptions().setThrowExceptionOnScriptError(false);
16         //狀態碼錯誤時,是否拋出異常
17         wc.getOptions().setThrowExceptionOnFailingStatusCode(false);
18         //是否容許使用ActiveX
19         wc.getOptions().setActiveXNative(false);
20         //等待js時間
21         wc.waitForBackgroundJavaScript(600*1000);
22         //設置Ajax異步處理控制器即啓用Ajax支持
23         wc.setAjaxController(new NicelyResynchronizingAjaxController());
24         //設置超時時間
25         wc.getOptions().setTimeout(1000000);
26         //不跟蹤抓取
27         wc.getOptions().setDoNotTrackEnabled(false);
28          WebRequest request=new WebRequest(new URL("https://www.marklines.com/cn/vehicle_sales/search_country/search/?searchID=587200"));
29          request.setAdditionalHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0");
30          request.setAdditionalHeader("Cookie","PLAY_LANG=cn; _plh=b9289d0a863a8fc9c79fb938f15372f7731d13fb; PLATFORM_SESSION=39034d07000717c664134556ad39869771aabc04-_ldi=520275&_lsh=8cf91cdbcbbb255adff5cba6061f561b642f5157&csrfToken=209f20c8473bc0518413c226f898ff79cd69c3ff-1539926671235-b853a6a63c77dd8fcc364a58&_lpt=%2Fcn%2Fvehicle_sales%2Fsearch&_lsi=1646321; _ga=GA1.2.2146952143.1539926675; _gid=GA1.2.1032787565.1539926675; _plh_notime=8cf91cdbcbbb255adff5cba6061f561b642f5157");
31         try {
32             //模擬瀏覽器打開一個目標網址
33             HtmlPage htmlPage = wc.getPage(request);
34             //爲了獲取js執行的數據 線程開始沉睡等待
35             Thread.sleep(1000);//這個線程的等待 由於js加載須要時間的
36             //以xml形式獲取響應文本
37             String xml = htmlPage.asXml();
38             //並轉爲Document對象return
39             return Jsoup.parse(xml);
40             //System.out.println(xml.contains("結果.xls"));//false
41         } catch (FailingHttpStatusCodeException e) {
42             e.printStackTrace();
43         } catch (MalformedURLException e) {
44             e.printStackTrace();
45         } catch (IOException e) {
46             e.printStackTrace();
47         }
48         return null;
49     }

 

4:返回的Document對象交給jsoup進行處理

  在這裏只作了一個簡單的輸出,查看了一下數據是否渲染所有。安全

 1 Document doc=getDocument();
 2         Element table=doc.select("table.table.table-bordered.aggregate_table").get(0);//獲取到表格
 3         Element tableContext=table.getElementsByTag("tbody").get(0);
 4         Elements contextTrs=tableContext.getElementsByTag("tr");
 5         System.out.println(contextTrs.size());
 6         
 7         
 8         String context=doc.toString();
 9         OutputStreamWriter pw = null;
10         pw = new OutputStreamWriter(new FileOutputStream("D:/test.txt"),"GBK");
11         pw.write(context);
12         pw.close();
相關文章
相關標籤/搜索