当前位置: 移动技术网 > IT编程>开发语言>Java > java+selenium 网易云音乐刷累计听歌数的方法

java+selenium 网易云音乐刷累计听歌数的方法

2019年07月19日  | 移动技术网IT编程  | 我要评论

背景

应该是在去年的时候,刷知乎看到一个问题,大概是说怎么刷网易云音乐个人累计听歌数,然后有一个高赞回答,贴了一段js代码,直接在浏览器console执行就可以了。当时试了下,直接一下子刷了有好几万。悲剧的是,第二天又回到原来的样子了,很明显这种方式被网易云音乐发现封掉了。而且后续网易云还针对累计听歌数加了一些限制,每天最多增加300首。今天带来一种通过java+selenium的方式,自动播放歌曲,来达到刷累计听歌数的效果。另外借助这个demo,对selenium的使用更加熟悉,也算是爬虫应用中一些有趣的东西了。

思路

登录,有以下两种方式可以选择:

a. 模拟web端的登录过程。优点:这种方式更加通用,便于动态切换账号。缺点:比直接使用cookie稍微麻烦一些,并且有一定几率会出现图形验证码,需要考虑这种情况。

b. 设置cookie。优点:不用处理登录过程,比较简单方便,在cookie的过期时间比较长情况下还是比较方便的,不用频繁切换。缺点:切换账号比较麻烦,不能达到自动化。我这里选择的该方式。

播放:上一个步骤中登录成功后,直接打开歌单列表页面。如下图

,在歌单列表页面可以看到。有3个地方是可以点击播放的,我最先想到是最下面一个播放按钮,然后一直保持底部播放组件的显示,实时获取播放的动态。尝试通过模拟点击播放按钮,始终不成功,最终点击最上面的播放按钮可以播放的。

获取播放动态:为了确定播放是否在正常进行,可以通过实时获取个人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) : "";
 }
}

运行注意事项

  • 修改自己相关chromedriver路径配置
  • 登录自己的web端网易云音乐:https://music.163.com/
  • 复制自己登录成功的原始cookies,至代码中的raw_cookies字段
  • 切换歌单,如果默认的歌单播放完成后,可以搜索一些没有播放过的歌单,类似https://music.163.com/#/playlist?id=22336453的url,提取出id,直接替换代码中的startid字段。

总结

  • 大家可能会有疑问,我想把这个任务放到自己的服务器上直接后台运行。这就是服务器上搭建selenium运行环境的问题了,可以参考我上一篇文章。阿里云和腾讯云最低配的服务器都能够跑起来的。
  • 另外这里为啥采用selenium的方式,有没有其他更简单的方式,直接通过简单的http请求的方式达到刷的效果。我个人尝试过像通过纯http 请求的方式,找到增加个人累计听歌数的请求,由于网银云的请求都做了加密,最终没有找到。所以就用selenium的方式来代替。

最后

完整工程代码见:

版权声明
作者:wycm
出处:https://my.oschina.net/wycm/blog/3023967

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网