柚子快報(bào)邀請(qǐng)碼778899分享:selenium 爬蟲(chóng)
柚子快報(bào)邀請(qǐng)碼778899分享:selenium 爬蟲(chóng)
selenium 可以動(dòng)態(tài)爬取網(wǎng)頁(yè)數(shù)據(jù),就像真實(shí)用戶操作瀏覽器一樣,從終端用戶的角度測(cè)試應(yīng)用程序,WebDriver通過(guò)原生瀏覽器支持或者瀏覽器擴(kuò)展直接控制瀏覽器
webdriver下載
因?yàn)閟elenuim對(duì)瀏覽器的版本存在兼容問(wèn)題,顧需要針對(duì)指定瀏覽器下載指定版本。
chrome版本下載
chrome 120.0.6099.71 64位
chrome 120.0.6099.71 32位
chrome 119.0.6045.124 64位
chrome 119.0.6045.124 32位
http://edgedl.me.gvt1.com/edgedl/release2/chrome/adoddphnvux2ay3bbbynsckujihq_120.0.6099.110/120.0.6099.110_chrome_installer.exe
https://edgedl.me.gvt1.com/edgedl/release2/chrome/adoddphnvux2ay3bbbynsckujihq_120.0.6099.110/120.0.6099.110_chrome_installer.exe
http://dl.google.com/release2/chrome/adoddphnvux2ay3bbbynsckujihq_120.0.6099.110/120.0.6099.110_chrome_installer.exe
https://dl.google.com/release2/chrome/adoddphnvux2ay3bbbynsckujihq_120.0.6099.110/120.0.6099.110_chrome_installer.exe
http://www.google.com/dl/release2/chrome/adoddphnvux2ay3bbbynsckujihq_120.0.6099.110/120.0.6099.110_chrome_installer.exe
https://www.google.com/dl/release2/chrome/adoddphnvux2ay3bbbynsckujihq_120.0.6099.110/120.0.6099.110_chrome_installer.exe
離線下載地址
https://chrome.noki.eu.org/
https://github.com/lyonna/ChromeOfflineInstallerDownloadAPI
1、添加依賴(lài)
2、工具類(lèi)
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* Selenium 工具類(lèi)
*
* @author kou
*/
@Slf4j
@RequiredArgsConstructor
@Component
public class SeleniumUtil {
private final ReptileProperties reptileProperties;
/**
* 獲取chromeDriver
*
* @return chromeDriver
*/
public WebDriver chromeDriver() {
// 加載驅(qū)動(dòng)路徑
System.setProperty("webdriver.chrome.driver", "D:/chromedriver.exe");
// Chrome默認(rèn)不允許跨機(jī)器調(diào)試,需要給啟動(dòng)命令加上白名單
System.setProperty("webdriver.chrome.whitelistedIps", "");
ChromeOptions options = new ChromeOptions();
// 開(kāi)啟一個(gè)實(shí)驗(yàn)性參數(shù)excludeSwitches,用來(lái)隱藏window.navigator.webdriver返回true,這個(gè)參數(shù)必須是List
options.setExperimentalOption("useAutomationExtension", false);
// 開(kāi)啟開(kāi)發(fā)者模式
options.setExperimentalOption("excludeSwitches", Lists.newArrayList("enable-automation"));
// 發(fā)現(xiàn)主要是這句是關(guān)鍵
options.addArguments("--disable-blink-features=AutomationControlled");
// options.addArguments("--incognito");
// options.addArguments("--disable-infobars");
//options.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36");
options.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36");
// 禁用沙箱
options.addArguments("--no-sandbox");
// 無(wú)頭瀏覽器,這樣不會(huì)打開(kāi)瀏覽器窗口
// options.addArguments("--headless");
// options.addArguments("--disable-gpu");
options.addArguments("--remote-allow-origins=*");
// 初始化一個(gè)谷歌瀏覽器實(shí)例,實(shí)例名稱(chēng)叫driver
WebDriver driver = new ChromeDriver(options);
return driver;
}
/**
* 獲取edgeDriver
*
* @return edgeDriver
*/
public WebDriver edgeDriver() {
// 加載驅(qū)動(dòng)路徑
System.setProperty("webdriver.edge.driver", "D:/msedgedriver.exe");
EdgeOptions options = new EdgeOptions();
// 開(kāi)啟一個(gè)實(shí)驗(yàn)性參數(shù)excludeSwitches,用來(lái)隱藏window.navigator.webdriver返回true,這個(gè)參數(shù)必須是List
options.setExperimentalOption("useAutomationExtension", false);
//開(kāi)啟開(kāi)發(fā)者模式
options.setExperimentalOption("excludeSwitches", Lists.newArrayList("enable-automation"));
// 發(fā)現(xiàn)主要是這句是關(guān)鍵
options.addArguments("--disable-blink-features=AutomationControlled");
options.addArguments("--incognito", "--disable-infobars");
// options.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36");
options.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36");
// 禁用沙箱
options.addArguments("--no-sandbox");
// 無(wú)頭瀏覽器,這樣不會(huì)打開(kāi)瀏覽器窗口
// options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--remote-allow-origins=*");
// 初始化一個(gè)谷歌瀏覽器實(shí)例,實(shí)例名稱(chēng)叫driver
WebDriver driver = new EdgeDriver(options);
return driver;
}
/**
* 獲取firefoxDriver
*
* @return firefoxDriver
*/
public WebDriver firefoxDriver() {
// 加載驅(qū)動(dòng)路徑
System.setProperty("webdriver.gecko.driver", "D:/geckodriver.exe");
System.setProperty("webdriver.chrome.whitelistedIps", "");
FirefoxOptions options = new FirefoxOptions();
options.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36");
// 無(wú)頭瀏覽器,這樣不會(huì)打開(kāi)瀏覽器窗口
options.addArguments("--headless");
// 初始化一個(gè)谷歌瀏覽器實(shí)例,實(shí)例名稱(chēng)叫driver
WebDriver driver = new FirefoxDriver(options);
return driver;
}
/**
* 獲取表頭
*
* @param table 表格
* @return 表頭
*/
public List
log.info("開(kāi)始解析表頭...");
// 獲取表頭
WebElement head = table.findElement(By.tagName("thead"));
if (null == head) {
return Collections.emptyList();
}
List
List
headths.forEach(t -> {
headList.add(t.getText());
});
log.info("表頭解析完成?。?!");
return headList;
}
/**
* 獲取表數(shù)據(jù)
*
* @param table 表格
* @return 表頭
*/
public List> getTableBody(WebElement table) {
log.info("開(kāi)始解析表數(shù)據(jù)...");
// 獲取表頭
WebElement tbody = table.findElement(By.tagName("tbody"));
if (null == tbody) {
return Collections.emptyList();
}
// 獲取body數(shù)據(jù)行
List
if (CollectionUtil.isEmpty(bodyTrs)) {
return Collections.emptyList();
}
List> bodyDatas = new ArrayList<>(bodyTrs.size());
bodyTrs.stream().forEach(r -> {
List
List
tds.forEach(d -> {
rows.add(d.getText());
});
bodyDatas.add(rows);
});
log.info("表數(shù)據(jù)解析完成?。?!");
return bodyDatas;
}
/**
* 將參數(shù)轉(zhuǎn)化為路徑參數(shù)
*
* @param params 參數(shù)
* @return 路徑參數(shù)
*/
public String convertPathParams(Map
if (CollectionUtil.isEmpty(params)) {
return "";
}
StringBuffer path = new StringBuffer();
for (Map.Entry
path.append(p.getKey()).append("=").append(p.getValue().toString()).append("&");
}
return path.substring(0, path.length() - 1);
}
}
3、爬取數(shù)據(jù)
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 數(shù)據(jù)接口實(shí)現(xiàn)類(lèi)
*
* @author kou
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class DataServiceImpl {
private final SeleniumUtil seleniumUtil;
/**
* 獲取頁(yè)面數(shù)據(jù)
*
* @return 數(shù)據(jù)
*/
@Override
public Map
try {
Map
String url = "url";
Map
params.put("pageNum", 1);
params.put("pageSize", 1000);
String fullUrl = url + seleniumUtil.convertPathParams(params);
WebDriver driver = seleniumUtil.firefoxDriver();
driver.get(fullUrl);
// 打開(kāi)一個(gè)站點(diǎn)
log.info("開(kāi)始訪問(wèn):{}", fullUrl);
driver.get(fullUrl);
String title = driver.getTitle();
log.info("網(wǎng)頁(yè):{}", title);
// 獲取表格數(shù)據(jù)
WebElement table = driver.findElement(By.id("table"));
//顯式等待,針對(duì)某個(gè)元素等待,等待超時(shí)時(shí)間100s,2s檢測(cè)一次
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(100), Duration.ofSeconds(2));
// wait.until(ExpectedConditions.presenceOfElementLocated(By.id("table")));
wait.until(new ExpectedCondition
@Override
public WebElement apply(WebDriver text) {
log.info("開(kāi)始檢查tbody數(shù)據(jù)是否已加載");
WebElement table = text.findElement(By.id("table")).findElement(By.tagName("tbody"));
if (!table.isDisplayed()) {
log.info("檢查結(jié)果:tbody數(shù)據(jù)未加載完,等待加載...");
return null;
}
log.info("檢查結(jié)果:tbody數(shù)據(jù)加載完成!!!");
return table;
}
});
// 獲取表頭
List
List> bodyList = seleniumUtil.getTableBody(table);
data.put("header", headList);
data.put("body", bodyList);
driver.close();
return data;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
4、抓取控制臺(tái)日志
Logs logs = driver.manage().logs();
LogEntries logEntries = logs.get(LogType.BROWSER);
for (LogEntry entry : logEntries) {
System.out.println(new Date(entry.getTimestamp()) + " " + entry.getLevel() + " " + entry.getMessage());
}
可以添加設(shè)置
ChromeOptions options = new ChromeOptions();
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.BROWSER, Level.ALL);
// options.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
options.setCapability("goog:loggingPrefs", logPrefs);
// 初始化一個(gè)谷歌瀏覽器實(shí)例,實(shí)例名稱(chēng)叫driver
ChromeDriver driver = new ChromeDriver(options);
5、獲取訪問(wèn)頁(yè)面的請(qǐng)求
ChromeDriver driver = seleniumUtil.chromeDriver();
DevTools devTools = driver.getDevTools();
devTools.createSession();
List
List
devTools.addListener(Network.requestWillBeSent(), request -> {
String requestType = String.valueOf(request.getType());
if (requestType.equals("Fetch") || requestType.equals("XHR")) {
requests.add(request.getRequest().getUrl());
}
});
devTools.addListener(Network.responseReceived(), response -> {
String requestType = String.valueOf(response.getType());
if (requestType.equals("Fetch") || requestType.equals("XHR")) {
responses.add(response.getResponse().getUrl());
}
});
// 啟用監(jiān)聽(tīng)器
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
driver.get("url");
6、禁止chrome自動(dòng)更新??disable_chrome_update.bat? 以管理員身份運(yùn)行
@echo off
chcp 65001 > nul
REM 停止并禁用 gupdate 服務(wù)
echo 正在停止和禁用 gupdate 服務(wù)...
sc stop gupdate
sc config gupdate start= disabled
echo gupdate 服務(wù)已成功停止和禁用。
REM 停止并禁用 gupdatem 服務(wù)
echo 正在停止和禁用 gupdatem 服務(wù)...
sc stop gupdatem
sc config gupdatem start= disabled
echo gupdatem 服務(wù)已成功停止和禁用。
REM 刪除 Chrome 的 Update 文件夾及其內(nèi)容
set "chrome_dir=C:\Program Files (x86)\Google\Update"
REM 嘗試結(jié)束 Chrome 進(jìn)程以便刪除文件
echo 正在結(jié)束 Chrome 進(jìn)程以便刪除文件...
taskkill /F /IM chrome.exe /T
echo Chrome 進(jìn)程已成功終止。
REM 等待一段時(shí)間以確保進(jìn)程被終止
echo 正在等待一段時(shí)間以確保進(jìn)程被終止...
ping 127.0.0.1 -n 5 > nul
REM 檢查 Chrome Update 文件夾是否存在
echo 正在檢查 Chrome Update 文件夾是否存在...
if exist "%chrome_dir%" (
REM 刪除文件夾及其內(nèi)容
echo 正在刪除 Chrome Update 文件夾及其內(nèi)容...
tasklist /FI "IMAGENAME eq chrome.exe" 2>NUL | find /I /N "chrome.exe">NUL
if "%ERRORLEVEL%"=="0" (
echo 關(guān)閉 Chrome 進(jìn)程...
taskkill /F /IM chrome.exe /T
)
echo 等待一段時(shí)間以確保進(jìn)程被終止...
ping 127.0.0.1 -n 5 > nul
rmdir /Q /S "%chrome_dir%"
REM 設(shè)置 Update 文件夾權(quán)限為拒絕對(duì) SYSTEM 用戶的完全控制
echo 正在設(shè)置 Chrome Update 文件夾權(quán)限...
icacls "%chrome_dir%" /deny SYSTEM:(F)
echo 更新服務(wù)已成功關(guān)閉并禁用,Chrome Update 文件夾已刪除,權(quán)限已修改。
) else (
echo Chrome Update 文件夾不存在,無(wú)需刪除。
)
pause
腳本功能解析 停止并禁用 gupdate 服務(wù):通過(guò)執(zhí)行命令sc stop gupdate和sc config gupdate start= disabled,停止并禁用 Chrome 的 gupdate 服務(wù)。
停止并禁用 gupdatem 服務(wù):通過(guò)執(zhí)行命令sc stop gupdatem和sc config gupdatem start= disabled,停止并禁用 Chrome 的 gupdatem 服務(wù)。
刪除 Chrome 的 Update 文件夾及其內(nèi)容:通過(guò)設(shè)置變量chrome_dir為 Chrome 的安裝路徑,然后使用命令rmdir /Q /S "%chrome_dir%"刪除整個(gè)文件夾及其內(nèi)容。若刪除不成功,則使用命令icacls "%chrome_dir%" /deny SYSTEM:(F)拒絕 SYSTEM 用戶對(duì)該文件夾的完全控制。 ?
柚子快報(bào)邀請(qǐng)碼778899分享:selenium 爬蟲(chóng)
參考閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。