日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

JAVA异步爬虫_Java 爬虫遇上数据异步加载,试试这两种办法!

發布時間:2024/1/23 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA异步爬虫_Java 爬虫遇上数据异步加载,试试这两种办法! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是 Java 爬蟲系列博文的第三篇,在上一篇 Java 爬蟲遇到需要登錄的網站,該怎么辦? 中,我們簡單的講解了爬蟲時遇到登錄問題的解決辦法,在這篇文章中我們一起來聊一聊爬蟲時遇到數據異步加載的問題,這也是爬蟲中常見的問題。

現在很多都是前后端分離項目,這會使得數據異步加載問題更加突出,所以你在爬蟲時遇到這類問題不必驚訝,不必慌張。對于這類問題的解決辦法總體來說有以下兩種:

1、內置一個瀏覽器內核

內置瀏覽器就是在抓取的程序中,啟動一個瀏覽器內核,使我們獲取到 js 渲染后的頁面,這樣我們就跟采集靜態頁面一樣了。這種工具常用的有以下三種:

Selenium

HtmlUnit

PhantomJs

這些工具都能幫助我們解決數據異步加載的問題,但是他們都存在缺陷,那就是效率不高而且不穩定。

2、反向解析法

什么是反向解析法呢?我們 js 渲染頁面的數據是通過 Ajax 的方式從后端獲取的,我們只需要找到對應的 Ajax 請求連接就 OK,這樣我們就獲取到了我們需要的數據,反向解析法的好處就是這種方式獲取的數據都是 json 格式的數據,解析起來也比較方便,另一個好處就是相對頁面來說,接口的變化概率更小。同樣它有兩個不足之處,一個是在 Ajax 時你需要有耐心有技巧,因為你需要在一大推請求中找到你想要的,另一個不足的地方就是對 JavaScript 渲染的頁面束手無策。

上面就是異步數據加載的兩種解決辦法,為了加深大家的理解和在項目中如何使用,我以采集網易要聞為例,網易新聞地址:https://news.163.com/ 。利用上訴的兩種方式來獲取網易要聞的新聞列表。網易要聞如下:

內置瀏覽器 Selenium 方式

Selenium 是一個模擬瀏覽器,進行自動化測試的工具,它提供一組 API 可以與真實的瀏覽器內核交互。在自動化測試上使用的比較多,爬蟲時解決異步加載也經常使用它,我們要在項目中使用 Selenium ,需要做兩件事:

1、引入 Selenium 的依賴包,在 pom.xml 中添加

org.seleniumhq.selenium

selenium-java

3.141.59

2、下載對應的 driver,例如我下載的 chromedriver,下載地址為:https://npm.taobao.org/mirrors/chromedriver/,下載后,需要將 driver 的位置寫到 Java 的環境變量里,例如我直接放在項目下,所以我的代碼為:

System.getProperties().setProperty("webdriver.chrome.driver", "chromedriver.exe");

完成上面兩步之后,我們就可以來編寫使用 Selenium 采集網易要聞啦。具體代碼如下:

/**

* selenium 解決數據異步加載問題

* https://npm.taobao.org/mirrors/chromedriver/

*

* @param url

*/

public void selenium(String url) {

// 設置 chromedirver 的存放位置

System.getProperties().setProperty("webdriver.chrome.driver", "chromedriver.exe");

// 設置無頭瀏覽器,這樣就不會彈出瀏覽器窗口

ChromeOptions chromeOptions = new ChromeOptions();

chromeOptions.addArguments("--headless");

WebDriver webDriver = new ChromeDriver(chromeOptions);

webDriver.get(url);

// 獲取到要聞新聞列表

List webElements = webDriver.findElements(By.xpath("//div[@class='news_title']/h3/a"));

for (WebElement webElement : webElements) {

// 提取新聞連接

String article_url = webElement.getAttribute("href");

// 提取新聞標題

String title = webElement.getText();

if (article_url.contains("https://news.163.com/")) {

System.out.println("文章標題:" + title + " ,文章鏈接:" + article_url);

}

}

webDriver.close();

}

運行該方法,得到結果如下:

我們使用 Selenium 已經正確的提取到了網易要聞的列表新聞。

反向解析法

反向解析法就是獲取到 Ajax 異步獲取數據的鏈接,直接獲取到新聞數據。如果沒有技巧的話,查找 Ajax 的過程將非常痛苦,因為一個頁面加載的鏈接太多了,看看網易要聞的 network:

有幾百條的請求,該如何查找到是哪條請求獲取的要聞數據呢?你不嫌麻煩的話,可以一個一個的去點,肯定能夠查找到的,另一種快捷的辦法是利用 network 的搜索功能,如果你不知道搜索按鈕,我在上圖已經圈出來啦,我們在要聞中隨便復制一個新聞標題,然后檢索一下,就可以獲取到結果,如下圖所示:

這樣我們就快速的獲取到了要聞數據的請求鏈接,鏈接為:https://temp.163.com/special/00804KVA/cm_yaowen.js?callback=data_callback,訪問該鏈接,查看該鏈接返回的數據,如下圖所示:

從數據我們可以看出,我們需要的數據都在這里啦,所以我們只需要解析這段數據接可以啦,要從這段數據中解析出新聞標題和新聞鏈接,有兩種方式,一種是正則表達式,另一種是將該數據轉成 json 或者 list。這里我選擇第二種方式,利用 fastjson 將返回的數據轉換成 JSONArray 。所以我們是要引入 fastjson ,在 pom.xml 中引入 fastjson 依賴:

com.alibaba

fastjson

1.2.59

除了引入 fastjson 依賴外,我們在轉換前還需要對數據進行簡單的處理,因為現在的數據并不符合 list 的格式,我們需要去掉 data_callback( 和最后面的 )。具體反向解析獲取網易要聞的代碼如下:

/**

* 使用反向解析法 解決數據異步加載的問題

*

* @param url

*/

public void httpclientMethod(String url) throws IOException {

CloseableHttpClient httpclient = HttpClients.createDefault();

HttpGet httpGet = new HttpGet(url);

CloseableHttpResponse response = httpclient.execute(httpGet);

if (response.getStatusLine().getStatusCode() == 200) {

HttpEntity entity = response.getEntity();

String body = EntityUtils.toString(entity, "GBK");

// 先替換掉最前面的 data_callback(

body = body.replace("data_callback(", "");

// 過濾掉最后面一個 )右括號

body = body.substring(0, body.lastIndexOf(")"));

// 將 body 轉換成 JSONArray

JSONArray jsonArray = JSON.parseArray(body);

for (int i = 0; i < jsonArray.size(); i++) {

JSONObject data = jsonArray.getJSONObject(i);

System.out.println("文章標題:" + data.getString("title") + " ,文章鏈接:" + data.getString("docurl"));

}

} else {

System.out.println("處理失敗!!!返回狀態碼:" + response.getStatusLine().getStatusCode());

}

}

編寫 main 方法,執行上面的方法,需要注意的地方是:這時候傳入的鏈接為https://temp.163.com/special/00804KVA/cm_yaowen.js?callback=data_callback 而不是 https://news.163.com/。得到如下結果:

兩種方法都成功的獲取到了網易要聞異步加載的新聞列表,對于這兩種方法的選取,我個人的傾向是使用反向解析法,因為它的性能和穩定是都要比內置瀏覽器內核靠譜,但是對于一些使用 JavaScript 片段渲染的頁面,內置瀏覽器又更加靠譜。所以根據具體情況選擇吧。

希望這篇文章對你有所幫助,下一篇是關于 爬蟲IP 被封的問題。如果你對爬蟲感興趣,不妨關注一波,相互學習,相互進步

源代碼:源代碼

文章不足之處,望大家多多指點,共同學習,共同進步

最后

打個小廣告,歡迎掃碼關注微信公眾號:「平頭哥的技術博文」,一起進步吧。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的JAVA异步爬虫_Java 爬虫遇上数据异步加载,试试这两种办法!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。