应该是在去年的时候,刷知乎看到一个问题,大概是说怎么刷网易云音乐我的累计听歌数,而后有一个高赞回答,贴了一段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![]()