最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java+selenium 網(wǎng)易云音樂刷累計(jì)聽歌數(shù)的方法

 更新時(shí)間:2019年06月12日 10:02:21   作者:wycm  
這篇文章主要介紹了java+selenium 網(wǎng)易云音樂刷累計(jì)聽歌數(shù)的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

背景

應(yīng)該是在去年的時(shí)候,刷知乎看到一個(gè)問題,大概是說怎么刷網(wǎng)易云音樂個(gè)人累計(jì)聽歌數(shù),然后有一個(gè)高贊回答,貼了一段js代碼,直接在瀏覽器console執(zhí)行就可以了。當(dāng)時(shí)試了下,直接一下子刷了有好幾萬。悲劇的是,第二天又回到原來的樣子了,很明顯這種方式被網(wǎng)易云音樂發(fā)現(xiàn)封掉了。而且后續(xù)網(wǎng)易云還針對(duì)累計(jì)聽歌數(shù)加了一些限制,每天最多增加300首。今天帶來一種通過java+selenium的方式,自動(dòng)播放歌曲,來達(dá)到刷累計(jì)聽歌數(shù)的效果。另外借助這個(gè)demo,對(duì)selenium的使用更加熟悉,也算是爬蟲應(yīng)用中一些有趣的東西了。

思路

登錄,有以下兩種方式可以選擇:

a. 模擬web端的登錄過程。優(yōu)點(diǎn):這種方式更加通用,便于動(dòng)態(tài)切換賬號(hào)。缺點(diǎn):比直接使用cookie稍微麻煩一些,并且有一定幾率會(huì)出現(xiàn)圖形驗(yàn)證碼,需要考慮這種情況。

b. 設(shè)置cookie。優(yōu)點(diǎn):不用處理登錄過程,比較簡(jiǎn)單方便,在cookie的過期時(shí)間比較長(zhǎng)情況下還是比較方便的,不用頻繁切換。缺點(diǎn):切換賬號(hào)比較麻煩,不能達(dá)到自動(dòng)化。我這里選擇的該方式。

播放:上一個(gè)步驟中登錄成功后,直接打開歌單列表頁面。如下圖

,在歌單列表頁面可以看到。有3個(gè)地方是可以點(diǎn)擊播放的,我最先想到是最下面一個(gè)播放按鈕,然后一直保持底部播放組件的顯示,實(shí)時(shí)獲取播放的動(dòng)態(tài)。嘗試通過模擬點(diǎn)擊播放按鈕,始終不成功,最終點(diǎn)擊最上面的播放按鈕可以播放的。

獲取播放動(dòng)態(tài):為了確定播放是否在正常進(jìn)行,可以通過實(shí)時(shí)獲取個(gè)人home頁面的累計(jì)聽歌數(shù)相關(guān)信息,用于監(jiān)控,由于已經(jīng)有一個(gè)頁面在播放歌曲了,為了不影響原有播放歌曲的頁面,可以打開一個(gè)新的tab頁來獲取個(gè)人home頁面,打開新的table頁,這里采用js的方式window.open('about:blank')

最終都會(huì)看到如下類似如下格式日志,那就說明成功了:

2019-03-26 09:25:10,406 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-00:00 / 00:00---當(dāng)前播放第1首歌曲, 累計(jì)聽歌:20572
2019-03-26 09:25:16,817 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-01:00 / 07:19---當(dāng)前播放第1首歌曲, 累計(jì)聽歌:20572
2019-03-26 09:25:23,157 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-01:06 / 07:19---當(dāng)前播放第1首歌曲, 累計(jì)聽歌:20572
2019-03-26 09:25:29,394 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-01:13 / 07:19---當(dāng)前播放第1首歌曲, 累計(jì)聽歌:20572
2019-03-26 09:25:35,592 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-01:19 / 07:19---當(dāng)前播放第1首歌曲, 累計(jì)聽歌:20572
2019-03-26 09:25:41,974 INFO [,main] - [com.github.wycm.Music163] - 伊犁河畔-01:25 / 07:19---當(dāng)前播放第1首歌曲, 累計(jì)聽歌: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) + "---當(dāng)前播放第" + count + "首歌曲, 累計(jì)聽歌:" + 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) : "";
 }
}

運(yùn)行注意事項(xiàng)

  • 修改自己相關(guān)chromedriver路徑配置
  • 登錄自己的web端網(wǎng)易云音樂:https://music.163.com/
  • 復(fù)制自己登錄成功的原始cookies,至代碼中的RAW_COOKIES字段
  • 切換歌單,如果默認(rèn)的歌單播放完成后,可以搜索一些沒有播放過的歌單,類似https://music.163.com/#/playlist?id=22336453的url,提取出id,直接替換代碼中的startId字段。

總結(jié)

  • 大家可能會(huì)有疑問,我想把這個(gè)任務(wù)放到自己的服務(wù)器上直接后臺(tái)運(yùn)行。這就是服務(wù)器上搭建selenium運(yùn)行環(huán)境的問題了,可以參考我上一篇文章。阿里云和騰訊云最低配的服務(wù)器都能夠跑起來的。
  • 另外這里為啥采用selenium的方式,有沒有其他更簡(jiǎn)單的方式,直接通過簡(jiǎn)單的Http請(qǐng)求的方式達(dá)到刷的效果。我個(gè)人嘗試過像通過純http 請(qǐng)求的方式,找到增加個(gè)人累計(jì)聽歌數(shù)的請(qǐng)求,由于網(wǎng)銀云的請(qǐng)求都做了加密,最終沒有找到。所以就用selenium的方式來代替。

最后

完整工程代碼見:https://github.com/wycm/crawler-set/tree/master/music163

版權(quán)聲明
作者:wycm
出處:https://my.oschina.net/wycm/blog/3023967

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java加載property文件配置過程解析

    Java加載property文件配置過程解析

    這篇文章主要介紹了java加載property文件配置過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • springboot2 jackson實(shí)現(xiàn)動(dòng)態(tài)返回類字段方式

    springboot2 jackson實(shí)現(xiàn)動(dòng)態(tài)返回類字段方式

    這篇文章主要介紹了springboot2 jackson實(shí)現(xiàn)動(dòng)態(tài)返回類字段方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java實(shí)現(xiàn)查找文件和替換文件內(nèi)容

    Java實(shí)現(xiàn)查找文件和替換文件內(nèi)容

    這篇文章主要為大家詳細(xì)介紹了Java語言如何實(shí)現(xiàn)查找文件和替換文件內(nèi)容功能,文中的示例代碼講解詳細(xì),感興趣的可以跟隨小編一起學(xué)習(xí)一下
    2022-08-08
  • Feign調(diào)用接口解決處理內(nèi)部異常的問題

    Feign調(diào)用接口解決處理內(nèi)部異常的問題

    這篇文章主要介紹了Feign調(diào)用接口解決處理內(nèi)部異常的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • nodejs與JAVA應(yīng)對(duì)高并發(fā)的對(duì)比方式

    nodejs與JAVA應(yīng)對(duì)高并發(fā)的對(duì)比方式

    這篇文章主要介紹了nodejs與JAVA應(yīng)對(duì)高并發(fā)的對(duì)比方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 深入剖析springBoot中的@Scheduled執(zhí)行原理

    深入剖析springBoot中的@Scheduled執(zhí)行原理

    這篇文章主要介紹了springBoot中的@Scheduled執(zhí)行原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Springboot傳輸數(shù)據(jù)時(shí)日期格式化問題

    Springboot傳輸數(shù)據(jù)時(shí)日期格式化問題

    這篇文章主要介紹了Springboot傳輸數(shù)據(jù)時(shí)日期格式化問題,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • SpringBoot執(zhí)行定時(shí)任務(wù)@Scheduled的方法

    SpringBoot執(zhí)行定時(shí)任務(wù)@Scheduled的方法

    這篇文章主要介紹了SpringBoot執(zhí)行定時(shí)任務(wù)@Scheduled的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 淺談maven單元測(cè)試設(shè)置代理

    淺談maven單元測(cè)試設(shè)置代理

    下面小編就為大家?guī)硪黄獪\談maven單元測(cè)試設(shè)置代理。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • Springboot注解之@EnableAutoConfiguration詳解

    Springboot注解之@EnableAutoConfiguration詳解

    這篇文章主要介紹了Springboot注解之@EnableAutoConfiguration詳解,@EnableAutoConfiguration是一個(gè)加載Starter目錄包之外的需要Spring自動(dòng)生成bean對(duì)象,本文對(duì)其進(jìn)行總結(jié),需要的朋友可以參考下
    2023-08-08

最新評(píng)論

福贡县| 南陵县| 吉首市| 呼伦贝尔市| 龙海市| 兴业县| 汝州市| 白城市| 比如县| 姜堰市| 凌云县| 古蔺县| 香港| 邓州市| 吉木乃县| 望江县| 崇左市| 牙克石市| 宿州市| 东明县| 水城县| 华亭县| 普陀区| 伊春市| 湖口县| 阿克| 沭阳县| 读书| 桐乡市| 沙湾县| 罗源县| 安塞县| 法库县| 沈阳市| 广南县| 武定县| 高陵县| 迁西县| 观塘区| 青田县| 罗江县|