應該是在去年的時候,刷知乎看到一個問題,大概是說怎麼刷網易雲音樂我的累計聽歌數,而後有一個高贊回答,貼了一段js代碼,直接在瀏覽器console執行就能夠了。當時試了下,直接一會兒刷了有好幾萬。悲劇的是,次日又回到原來的樣子了,很明顯這種方式被網易雲音樂發現封掉了。並且後續網易雲還針對累計聽歌數加了一些限制,天天最多增長300首。今天帶來一種經過java+selenium的方式,自動播放歌曲,來達到刷累計聽歌數的效果。另外借助這個demo,對selenium的使用更加熟悉,也算是爬蟲應用中一些有趣的東西了。css
登陸,有如下兩種方式能夠選擇: a. 模擬web端的登陸過程。優勢:這種方式更加通用,便於動態切換帳號。缺點:比直接使用cookie稍微麻煩一些,而且有必定概率會出現圖形驗證碼,須要考慮這種狀況。 b. 設置cookie。優勢:不用處理登陸過程,比較簡單方便,在cookie的過時時間比較長狀況下仍是比較方便的,不用頻繁切換。缺點:切換帳號比較麻煩,不能達到自動化。我這裏選擇的該方式。java
播放:上一個步驟中登陸成功後,直接打開歌單列表頁面。以下圖git
獲取播放動態:爲了肯定播放是否在正常進行,能夠經過實時獲取我的home頁面的累計聽歌數相關信息,用於監控,因爲已經有一個頁面在播放歌曲了,爲了避免影響原有播放歌曲的頁面,能夠打開一個新的tab頁來獲取我的home頁面,打開新的table頁,這裏採用js的方式window.open('about:blank')
。最終都會看到以下相似以下格式日誌,那就說明成功了:程序員
2019-03-26 09:25:10,406 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-00:00 / 00:00---當前播放第1首歌曲, 累計聽歌:20572
2019-03-26 09:25:16,817 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-01:00 / 07:19---當前播放第1首歌曲, 累計聽歌:20572
2019-03-26 09:25:23,157 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-01:06 / 07:19---當前播放第1首歌曲, 累計聽歌:20572
2019-03-26 09:25:29,394 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-01:13 / 07:19---當前播放第1首歌曲, 累計聽歌:20572
2019-03-26 09:25:35,592 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-01:19 / 07:19---當前播放第1首歌曲, 累計聽歌:20572
2019-03-26 09:25:41,974 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-01:25 / 07:19---當前播放第1首歌曲, 累計聽歌:20572
複製代碼
package com.github.wycm;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by wycm
*/
public class Music163 {
private static Logger logger = LoggerFactory.getLogger(Music163.class);
//拷貝登陸成功的瀏覽器原始cookie
private final static String RAW_COOKIES = "cookie1=value1; cookie2=value2";
private final static String CHROME_DRIVER_PATH = "/Users/wangyang/Downloads/chromedriver";
//歌曲列表id
private static String startId = "22336453";
private static String userId = null;
private static Set<String> playListSet = new HashSet<>();
private static Pattern pattern = Pattern.compile("<span class=\"j-flag time\"><em>(.*?)</em>(.*?)</span>");
private static Pattern songName = Pattern.compile("class=\"f-thide name fc1 f-fl\" title=\"(.*?)\"");
private static ChromeOptions chromeOptions = new ChromeOptions();
private static WebDriver driver = null;
static {
System.setProperty("webdriver.chrome.driver", CHROME_DRIVER_PATH);
chromeOptions.addArguments("--no-sandbox");
}
public static void main(String[] args) throws InterruptedException {
while (true){
try {
driver = new ChromeDriver(chromeOptions);
playListSet.add(startId);
invoke();
} catch (Exception e){
logger.error(e.getMessage(), e);
} finally {
driver.quit();
}
Thread.sleep(1000 * 10);
}
}
/**
* 初始化cookies
*/
private static void initCookies(){
Arrays.stream(RAW_COOKIES.split("; ")).forEach(rawCookie -> {
String[] ss = rawCookie.split("=");
Cookie cookie = new Cookie.Builder(ss[0], ss[1]).domain(".163.com").build();
driver.manage().addCookie(cookie);
});
}
private static void invoke() throws InterruptedException {
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(15, TimeUnit.SECONDS);
String s = null;
driver.get("http://music.163.com/");
initCookies();
driver.get("http://music.163.com/");
s = driver.getPageSource();
userId = group(s, "userId:(\\d+)", 1);
driver.get("https://music.163.com/#/playlist?id=" + startId);
driver.switchTo().frame("contentFrame");
WebElement element = driver.findElement(By.cssSelector("[id=content-operation]>a:first-child"));
element.click();
((JavascriptExecutor) driver).executeScript("window.open('about:blank')");
ArrayList<String> tabs = new ArrayList<String>(driver.getWindowHandles());
driver.switchTo().window(tabs.get(0));
driver.switchTo().defaultContent();
int i = 0;
String lastSongName = "";
int count = 0;
while (true){
if(i > Integer.MAX_VALUE - 2){
break;
}
i++;
s = driver.getPageSource();
driver.switchTo().window(tabs.get(1)); //switches to new tab
String songs = null;
try{
driver.get("https://music.163.com/user/home?id=" + userId);
driver.switchTo().frame("contentFrame");
songs = group(driver.getPageSource(), "累積聽歌(\\d+)首", 1);
} catch (TimeoutException e){
logger.error(e.getMessage(), e);
}
driver.switchTo().window(tabs.get(0));
Matcher matcher = pattern.matcher(s);
Matcher songNameMatcher = songName.matcher(s);
if (matcher.find() && songNameMatcher.find()){
String songNameStr = songNameMatcher.group(1);
if (!songNameStr.equals(lastSongName)){
count++;
lastSongName = songNameStr;
}
logger.info(songNameStr + "-" + matcher.group(1) + matcher.group(2) + "---當前播放第" + count + "首歌曲, 累計聽歌:" + songs);
} else {
logger.info("解析歌曲播放記錄或歌曲名失敗");
}
Thread.sleep(1000 * 30);
}
}
public static String group(String str, String regex, int index) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
return matcher.find() ? matcher.group(index) : "";
}
}
複製代碼
https://music.163.com/#/playlist?id=22336453
的url,提取出id,直接替換代碼中的startId字段。版權聲明 做者:wycm
出處:juejin.im/post/5c9ac9… 您的支持是對博主最大的鼓勵,感謝您的認真閱讀。
本文版權歸做者全部,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。
github![]()