python爬取網易雲周傑倫所有專輯,歌曲,評論,並完成可視化分析

来源:https://www.cnblogs.com/ZFBG/archive/2018/04/25/8947541.html
-Advertisement-
Play Games

恢復內容開始 去年在網路上有一篇文章特別有名:我分析42萬字的歌詞,為搞清楚民謠歌手們在唱些什麼。這篇文章的作者是我大學的室友,隨後網路上出現了各種以為爬取了XXX,發現了XXX為名的文章。我想了想,我能不能也通過爬蟲來做些什麼呢?先入為主,我也以歌曲作為切入口 周傑倫,是的,我們這一代的生活成長, ...


---恢復內容開始---

  去年在網路上有一篇文章特別有名:我分析42萬字的歌詞,為搞清楚民謠歌手們在唱些什麼。這篇文章的作者是我大學的室友,隨後網路上出現了各種以為爬取了XXX,發現了XXX為名的文章。我想了想,我能不能也通過爬蟲來做些什麼呢?先入為主,我也以歌曲作為切入口---周傑倫,是的,我們這一代的生活成長,總是離不開周董的聲音的陪伴,那我就來爬取周董的歌曲,歌曲評論,歌詞,以及各種有用的信息並做一個可視化吧。

  這篇文章適合於python純小白,因為本人也是python剛剛入門,裡面可能很多語句是冗長的,甚至可能有一些尚未發現的BUG,這個伴隨著我們繼續學習來慢慢消解吧。接下來 我把裡面會用到的東西在這裡做一個總結吧:本文用到了兩門解釋性編程語言python + bash(shell),為什麼用shell,我會在後面具體分析。用到的模塊requests,re,os,jieba,glob,json,lxml,pyecharts,heapq,collections.看到這麼多模塊,大家一定很頭痛,其實最開始我也沒想到會用到這麼多。不過隨著程式的進行,這些模塊自然的就出現在程式里,每一個模塊我們沒必要特別瞭解。但是用法需要掌握。 話不多說,接下來就進入我們的正題吧。

一.找到需要爬取的內容,分析網頁,抓包查看交互內容

  首先我們先進入到我們需要抓取的內容的地址。http://music.163.com/#  這是網易雲音樂的首頁,我們的目的是抓取周傑倫的所有歌曲,歌詞,已經評論,那我們在搜索處輸入周傑倫得到這張圖,我們發現這裡面只有最多50首歌(很多人分析網易雲的歌曲就只選取TOP50),我們想要的是全部,所以這個URL不符合要求,我們繼續尋找其他的URL地址。我在這裡花了不少時間,最後找到了一個間接的方法,首先抓取周傑倫的全部專輯信息,然後通過專輯信息再去尋找全部歌曲(目前在網易雲上我還沒發現什麼方法可以直接獲取全部歌曲名字)。好了確定好了方針,我們第一步抓取所有專輯 進入http://music.163.com/#/artist/album?id=6452如下圖所示!在這裡面我們可以看到周傑倫所有專輯信息點擊下一頁 觀察url發現變成了  http://music.163.com/#/artist/album?id=6452&limit=12&offset=12 這樣!!!所以有點html基礎的人都知道這裡的limit=12是每頁顯示專輯的數量。OK,接下來我們就來獲取專輯吧!我們在頁面輸入http://music.163.com/#/artist/album?id=6452&limit=100&offset=12(改成100 避免多次抓取,一次抓去完),在谷歌的抓包工具(F12)裡面查看交互信息發現如下:

是的你沒看錯,這就是我們想要的信息,那事情就變得簡單的,我們沒必要用複雜的工具比如(selenium)去載入整個頁面,(事實上,如果還沒想到抓取歌曲的方法,我估計就得用它了),我們再看header裡面有什麼這裡面的string我們不用管了,因為它已經在我們的url裡面了,我們只需要看request headers 這個就是我們給伺服器發送的東西,發送之後,伺服器返回給我們的就是network裡面的信息。好,接下來我們偽造瀏覽器發送請求。具體代碼如下:

    def GetAlbum(self):
        urls="http://music.163.com/artist/album?id=6452&limit=100&offset=0"
        headers={
        'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Encoding':'gzip, deflate, br',
        'Accept-Language':'zh-CN,zh;q=0.9',
        'Connection':'keep-alive',
        'Cookie':'_iuqxldmzr_=32; _ntes_nnid=dc7dbed33626ab3af002944fabe23bc4,1524151830800; _ntes_nuid=dc7dbed33626ab3af002944fabe23bc4; __utmc=94650624; __utmz=94650624.1524151831.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=94650624.1505452853.1524151831.1524151831.1524176140.2; WM_TID=RpKJQQ90pzUSYfuSWgFDY6QEK1Gb4Ulg; JSESSIONID-WYYY=ZBmSOShrk4UKH5K%5CVasEPuc0b%2Fq6m5eAE91jWCmD6UpdB2y4vbeazO%2FpQK%5CgiBW0MUDDWfB1EuNaV5c4wIJZ08hYQKDhpsHnDeMAgoz98dt%2B%2BFfhdiiNJw9Y9vRR5S4GU%2FziFp%2BliFX1QTJj%2BbaIGD3YxVzgumklAwJ0uBe%2FcGT6VeQW%3A1524179765762; __utmb=94650624.24.10.1524176140',
        'Host':'music.163.com',
        'Referer':'https://music.163.com/',
        'Upgrade-Insecure-Requests':'1',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
        }
        html = requests.get(urls,headers=headers)
        html1=etree.HTML(html.text)
        html_data=html1.xpath('//div[@class="u-cover u-cover-alb3"]')[0]
        pattern = re.compile(r'<div class="u-cover u-cover-alb3" title=(.*?)>')
        items = re.findall(pattern, html.text)
        cal=0
        # 首先刪除這個沒文件,要不然每次都是追加
        if(os.path.exists("專輯信息.txt")):
            os.remove("專輯信息.txt")
        #刪除文件避免每次都要重覆寫入
        if (os.path.exists("專輯歌曲信息.txt")):
            os.remove("專輯歌曲信息.txt")
        for i in items:
            cal+=1
            #這裡需要註意i是有雙引號的,所以需要註意轉換下
            p=i.replace('"','')
            #這裡在匹配裡面使用了字元串,註意下
            pattern1=re.compile(r'<a href="/album\?id=(.*?)" class="tit s-fc0">%s</a>'%(p))
            id1= re.findall(pattern1,html.text)
        #   print("專輯的名字是:%s!!專輯的ID是%s:"%(i,items1))
            with open("專輯信息.txt",'a') as f:
                f.write("專輯的名字是:%s!!專輯的ID是%s \n:"%(i,id1))
                f.close()
                self.GetLyric1(i,id1)
      #  print("總數是%d"%(cal))
        print("獲取專輯以及專輯ID成功!!!!!")

 

這裡面用到了xpath來找到對應標簽裡面數據,代碼不重要,思想懂了就行(代碼單獨執行可行)

執行結果如下

 

 

二.抓取歌曲信息。

  通過上面我們已經抓取到了專輯的信息,接下來我們就通過專輯,來獲取歌曲信息

看這幅圖,我想你已經懂了,頁面組成http://music.163.com/#/album?id=!!!  !!!這裡填寫專輯ID,我們在network裡面找到了所有歌曲的信息接下來我們看header同樣的道理我們通過偽造方式發送信息,獲取歌曲信息!!直接上代碼

 def GetLyric1(self,album,id1):
        urls1 = "http://music.163.com/#/album?id="
        urls2 = str(id1)
        urls3= urls1+urls2
        #將不要需要的符號去掉
        urls=urls3.replace("[","").replace("]","").replace("'","").replace("#/","")
        headers={
            'Cookie': '_iuqxldmzr_=32; _ntes_nnid=dc7dbed33626ab3af002944fabe23bc4,1524151830800; _ntes_nuid=dc7dbed33626ab3af002944fabe23bc4; __utmz=94650624.1524151831.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=94650624.1505452853.1524151831.1524176140.1524296365.3; __utmc=94650624; WM_TID=RpKJQQ90pzUSYfuSWgFDY6QEK1Gb4Ulg; JSESSIONID-WYYY=7t6F3r9Uzy8uEXHPnVnWTXRP%5CSXg9U3%5CN8V5AROB6BIe%2B4ie5ch%2FPY8fc0WV%2BIA2ya%5CyY5HUBc6Pzh0D5cgpb6fUbRKMzMA%2BmIzzBcxPcEJE5voa%2FHA8H7TWUzvaIt%2FZnA%5CjVghKzoQXNM0bcm%2FBHkGwaOHAadGDnthIqngoYQsNKQQj%3A1524299905306; __utmb=94650624.21.10.1524296365',
            'Host': 'music.163.com',
            'Referer': 'http://music.163.com/',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36'
        }
        html = requests.get(urls, headers=headers)
        html1 = etree.HTML(html.text)
       # soup = BeautifulSoup(html1, 'html.parser', from_encoding='utf-8')
       # tags = soup.find_all('li', class_="have-img")
        html_data = html1.xpath('//ul[@class="f-hide"]//a')
        for i in html_data:
            #註意這個用法
            html_data1=i.xpath('string(.)')
            #獲取歌曲的id
            html_data2=str(html_data1)
            pattern1=re.compile(r'<li><a href="/song\?id=(\d+?)">%s</a></li>'%(html_data2))
            items = re.findall(pattern1,html.text)
  #          print("歌曲的名稱為: %s"%(html_data2))
 #           print("歌曲的id為: %s"%(items))
            with open("專輯歌曲信息.txt", 'a') as f:
                print(len(items))
                if (len(items) > 0):
                    f.write("歌曲的名字是: %s!!歌曲的ID是%s \n" % (html_data2, items))
                    f.close()
                print("獲取歌曲 %s 以及歌曲的ID %s寫入文件成功"%(html_data2, items))
            #http://music.163.com/#/song?id=185617
               # if(len())
    def GetLyric2(self):
        #首先刪除原來的文件,避免重覆寫入
        for i in glob.glob("*熱評*"):
            os.remove(i)
        for i in glob.glob("*歌曲名*"):
            os.remove(i)
        #直接讀取所有內容
        file_object=open("專輯歌曲信息.txt",)
        list_of_line=file_object.readlines()
        aaa=1
        namelist = ""
        for i in  list_of_line:
            # 歌曲的名字是: 同一種調調!!歌曲的ID是['186020']
            pattern1 = re.compile(r'歌曲的名字是: (.*?)!!歌曲的ID是')
            pattern2 = re.compile(r'歌曲的ID是\[(.*?)\]')
            items1 = str(re.findall(pattern1, i)).replace("[","").replace("]","").replace("'","")
            items2 = str(re.findall(pattern2, i)).replace("[","").replace("]","").replace('"',"").replace("'","")

            headers = {
                'Request URL': 'http://music.163.com/weapi/song/lyric?csrf_token=',
                'Request Method': 'POST',
                'Status Code': '200 OK',
                'Remote Address': '59.111.160.195:80',
                'Referrer Policy': 'no-referrer-when-downgrade'
            }
      #      http://music.163.com/api/song/lyric?id=186017&lv=1&kv=1&tv=-1
            urls="http://music.163.com/api/song/lyric?"+"id="+str(items2)+'&lv=1&kv=1&tv=-1'
       #     urls = "http://music.163.com/api/song/lyric?id=186018&lv=1&kv=1&tv=-1"
            #print(urls)
            html = requests.get(urls, headers=headers)
            json_obj = html.text
            j = json.loads(json_obj)
            try:
                lrc = j['lrc']['lyric']
                pat = re.compile(r'\[.*\]')
                lrc = re.sub(pat,"",lrc)
                lrc = lrc.strip()
                print(lrc)
                lrc = str(lrc)
                with open("歌曲名-"+items1+".txt", 'w',encoding='utf-8') as f:
                    f.write(lrc)
                aaa+=1
                namelist=namelist + items1 + ".txt"+","
#調用獲取評論方法,並且把熱評寫入文件
                self.GetCmmons(items1,items2)
            except:
                print("歌曲有錯誤 %s !!"%(items1))
            #讀取所有文件,並且把所有的信息輸入到一個文件裡面去
           # html1 = etree.HTML(html.text)
        print("歌曲一共爬取了%s首 "%(aaa))
        print(namelist)

 

 

上面需要註意:xpath來獲取需要的信息,利用正則來獲取ID(其實有很多方法)

結果如下

 

同樣的方法!!我們打開一首歌曲一樣的道理,我們分析network來獲取我們需要的信息歌詞,評論!!直接上代碼

 def GetCmmons(self,name,id):
        self.name=name
        self.id=id
        #刪除原來的文件 避免重覆爬取
      #  urls="http://music.163.com/weapi/v1/resource/comments/R_SO_4_415792918?csrf_token="
        urls="http://music.163.com/api/v1/resource/comments/R_SO_4_"+str(id)
        headers={
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'Accept-Encoding': 'gzip, deflate',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Cache-Control': 'max-age=0',
            'Connection': 'keep-alive',
            'Cookie': '_iuqxldmzr_=32; _ntes_nnid=dc7dbed33626ab3af002944fabe23bc4,1524151830800; _ntes_nuid=dc7dbed33626ab3af002944fabe23bc4; __utmz=94650624.1524151831.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); WM_TID=RpKJQQ90pzUSYfuSWgFDY6QEK1Gb4Ulg; JSESSIONID-WYYY=BgqSWBti98RpkHddEBZcxnxMIt4IdbCqXGc0SSxKwvRYlqbXDAApbgN%2FQWQ8vScdXfqw7adi2eFbe30tMZ13mIv9XOAv8bhrQYC6KRajksuYWVvTbv%2BOu5oCypc4ylh2Dk5R4TqHgRjjZgqFbaOF73cJlSck3lxcFot9jDmE9KWnF%2BCk%3A1524380724119; __utma=94650624.1505452853.1524151831.1524323163.1524378924.5; __utmc=94650624; __utmb=94650624.8.10.1524378924',
            'Host': 'music.163.com',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36'
        }
        html = requests.get(urls,headers=headers)
        html.encoding= 'utf8'
      #  html_data = html1.xpath('//div[@class="u-cover u-cover-alb3"]')[0]
       # pattern = re.compile(r'<div class="u-cover u-cover-alb3" title=(.*?)>')
        #items = re.findall(pattern, html.text)
        #print(html.text)
        #使用json格式化輸出
        json_obj = html.text
        j = json.loads(json_obj)
        i=j['hotComments']
        for uu in  i:
            print
            username=uu["user"]['nickname']
            likedCount1 = str(uu['likedCount'])
            comments=uu['content']
            with open(name + "的熱評hotComment" +".txt" , 'a+',encoding='utf8') as f:
                f.write("用戶名是 "+username+"\n")
                f.write("用戶的評論是 "+comments+"\n")
                f.write("被點贊的次數是  " + str(likedCount1) +"\n")
                f.write("----------華麗的的分割線-------------"+"\n")
                f.close()

 

上面需要註意的是:利用json獲取需要的數據(至少比正則快點)

結果如下: 

 

 

到這裡!!我們已經完成了所有用數據的爬取

三 數據分析,可視化

  如果數據不利用,就如同一張白紙一樣,接下來我們就對數據進行全面的分析

 第一步,我們先把數據合併到一個文件里

 def MergedFile(self):
        aaa=0
        for i in glob.glob("*歌曲名*"):
            file_object = open(i,'r',encoding='UTF-8')
            list_of_line = file_object.readlines()
            for p in list_of_line:
                if  "作詞" in p  or "作曲" in p or "混音助理" in p or "混音師" in p or "錄音師" in p or "執行製作" in p  or  "編曲" in p or "製作人" in p or "錄音工程" in p or "錄音室" in p or "混音錄音室" in p or "混音工程" in p or "Programmer" in p or p == "\n" or "和聲" in p  or "吉他" in p or "錄音助理" in p or "陳任佑鼓" in p or "周傑倫" in p:
                    aaa+=1
                    print(p)
                else:
                    with open ("allLyric"+".txt","a",encoding='UTF-8') as f :
                        f.write(p)
                        f.write("\n")
            print(aaa)
          #合併歌曲
        file1 = open('allLyric.txt', 'r', encoding='utf-8')  # 要去掉空行的文件
        file2 = open('allLyric1.txt', 'w', encoding='utf-8')  # 生成沒有空行的文件
        try:
            for line in file1.readlines():
                if line == '\n':
                    line = line.strip("\n")
                file2.write(line)
        finally:
            file1.close()
            file2.close()
        print("合併歌詞文件完成")

 

上面需要註意的是:我們合併數據的時候,可以選擇性的刪除一些無用數據

結果如下

下麵我們對周傑倫歌曲進行情緒化分析

    def EmotionAnalysis(self):
        from snownlp import SnowNLP
        from pyecharts import Bar
        xzhou=[]
        yzhou=[]
        for i in  glob.glob("*歌曲名*"):
            count=0
            allsen=0
            with open(i,'r', encoding='utf-8') as fileHandel:
                fileList = fileHandel.readlines()
                for p in fileList:
                    if  "作詞" in p  or "作曲" in p or "" in p  or "混音師" in p or "錄音師" in p or "執行製作" in p  or  "編曲" in p or "製作人" in p or "錄音工程" in p or "錄音室" in p or "混音錄音室" in p or "混音工程" in p or "Programmer" in p or p == "\n":
                        pass
                    else:
                        s = SnowNLP(p)
                      #  print(s.sentences[0])
                        s1 = SnowNLP(s.sentences[0])
                        #print(type(s1))
                        count+=1
                        allsen+=s1.sentiments
            i=str(i)
            xzhou1 = i.split("-", 1)[1].split(".",1)[0]
            xzhou.append(xzhou1)
            avg=int(allsen)/count
            yzhou.append(avg)
            #print("%s這首歌的情緒為%s"%(i,avg))
            fileHandel.close()
        bar = Bar("柱狀圖數據堆疊示例")
        bar.add("周傑倫歌曲情緒可視化", xzhou, yzhou, is_stack=True,xaxis_interval=0)
        bar.render(r"D:\學習\untitled4\allpicture\周傑倫歌曲情緒全部.html")
        #顯示最好的前五首歌
        import  heapq
        yzhou1 = heapq.nlargest(10, yzhou)
        temp = map(yzhou.index, heapq.nlargest(10, yzhou))
        temp = list(temp)
        xzhou1 = []
        for i in temp:
            xzhou1.append(xzhou[i])
        # 情緒前十首歌個圖
        bar = Bar("周傑倫歌曲情緒較好前十首歌")
        bar.add("周傑倫歌曲情緒可視化", xzhou1, yzhou1, is_stack=True)
        bar.render(r"D:\學習\untitled4\allpicture\周傑倫歌曲最積極情緒top10.html")
        #顯示最差的十首歌
        yzhou1 = heapq.nsmallest(10, yzhou)
        temp = map(yzhou.index, heapq.nsmallest(10, yzhou))
        temp = list(temp)
        xzhou1 = []
        for i in temp:
            xzhou1.append(xzhou[i])
       # print(xzhou1)
        #print(yzhou1)
        # 情緒前十首歌個圖
        bar = Bar("周傑倫歌曲情緒較差前十首歌")
        bar.add("周傑倫歌曲情緒可視化",xzhou1, yzhou1,xaxis_interval=0,xzhou1_label_textsize=6)
        bar.render(r"D:\學習\untitled4\allpicture\周傑倫歌曲最消極情緒top10.html")
        print(xzhou1)

 

下麵完成數據詞頻各種分析

  #定義結巴分詞的方法以及處理過程
    def splitSentence(self,inputFile, outputFile):
        fin = open(inputFile, 'r', encoding='utf-8')
        fout = open(outputFile, 'w', encoding='utf-8')
        for line in fin:
            line = line.strip()
            line = jieba.analyse.extract_tags(line)
            outstr = " ".join(line)
            fout.write(outstr + '\n')
        fin.close()
        fout.close()
        #下麵的程式完成分析前十的數據出現的次數
        f = open("分詞過濾後.txt", 'r', encoding='utf-8')
        a = f.read().split()
        b = sorted([(x, a.count(x)) for x in set(a)], key=lambda x: x[1], reverse=True)
        print(sorted([(x, a.count(x)) for x in set(a)], key=lambda x: x[1], reverse=True))

#輸出頻率最多的前十個字,裡面調用splitSentence完成頻率出現最多的前十個詞的分析
    def LyricAnalysis(self):
        import jieba
        file = 'allLyric1.txt'
        #這個技巧需要註意
        alllyric = str([line.strip() for line in open('allLyric1.txt',encoding="utf-8").readlines()])
#獲取全部歌詞,在一行裡面
        alllyric1=alllyric.replace("'","").replace(" ","").replace("?","").replace(",","").replace('"','').replace("?","").replace(".","").replace("!","").replace(":","")
       # print(alllyric1)
       #在這裡用結巴分詞來分詞過濾並且輸出到一個文件裡面,這個ting.txt
       #import jieba.analyse 這裡必須引入
        jieba.analyse.set_stop_words("ting.txt")
        self.splitSentence('allLyric1.txt', '分詞過濾後.txt')
        #下麵是詞頻統計
        import collections
        # 讀取文本文件,把所有的漢字拆成一個list
        f = open("分詞過濾後.txt", 'r', encoding='utf8')  # 打開文件,並讀取要處理的大段文字
        txt1 = f.read()
        txt1 = txt1.replace('\n', '')  # 刪掉換行符
        txt1 = txt1.replace(' ', '')  # 刪掉換行符
        txt1 = txt1.replace('.', '')  # 刪掉逗號
        txt1 = txt1.replace('.', '')  # 刪掉句號
        txt1 = txt1.replace('o', '')  # 刪掉句號
        mylist = list(txt1)
        mycount = collections.Counter(mylist)
        for key, val in mycount.most_common(10):  # 有序(返回前10個)
            print(key, val)

 

好了!!其實分析語法沒那麼重要,實驗的方法也很多!!

我們來看下結果把

 

 

 

 

 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言: 在開發當中,經常會驗證用戶登錄狀態和獲取用戶信息。如果每次都手動調用用戶信息查詢介面,會非常的繁瑣,而且代碼冗餘。為了提高開發效率,因此就有了今天這篇文章。 思路: 用戶請求我們的方法會攜帶一個Token,通過Filter過濾器將會員信息查出來並放到request請求參數中。接著在Cotro ...
  • final實例域 實例域(對象的屬性)可修飾為final。修飾為final後,在構建對象時必須初始化這個實例域。若沒有在實例域進行初始化,那麼必須在每個構造器內初始化這個實例域(否則會編譯錯誤)。 表明在後面的操作中,不能夠再對它進行修改。即沒有對應的域更改器(set)方法. final修飾大部分都 ...
  • 放下該放下的,跟從自己的心,試著去瞭解我自己。 2016.07畢業至今。在一家台資代工廠工作。 時間過得飛快,身邊同時進來的10餘人,僅剩3人。這輛公交車,大家說下就下了。 2016年低,和中神一起下班的路上,我賣弄自己寫的VBA腳本,如何快速處理表格云云。中神不甘示弱“我寫的python腳本可以抓 ...
  • 基礎數據類型: 六個標準的數據類型: Number(數字) String(字元串) List(列表) Tuple(元祖) Sets(集合) Dictionary(字典) ———————— 不可變數據(四個):Number(數字)、String(字元串)、Tuple(元祖)、Sets(集合) 可變數據 ...
  • 上接Spring框架學習筆記(三) 聲明式事務管理(xml配置) 1 配置文件方式使用aop思想配置 第一步 配置事務管理器 第二步 配置事務增強 第三步 配置切麵 聲明式事務管理(註解) 第一步 配置事務管理器 第二步 配置事務註解 第三步 在要使用事務的方法所在類上面添加註解 SSH三大框架整合 ...
  • Java時間轉換的方法 系統開發過程中常因為時間參數的存儲和呈現方式的問題產生爭議,再加上考慮不同時區的時間在同一系統存儲和展示的情況更為複雜。通常的設計方案是:存儲的時候,為了不讓數據混亂,統一按照UTC+00:00時區的毫秒級長整型數字時間戳來存儲;展示的時候,為了讓用戶方便,按照用戶關註的時區 ...
  • Java中的static關鍵字主要用於記憶體管理。我們可以應用static關鍵字在變數、方法、塊和嵌套類中。 static關鍵字屬於類,而不是類的實例。 靜態(static)可以是: 變數(也稱為類變數) 方法(也稱為類方法) 代碼塊 嵌套類 修飾變數 被static修飾的變數稱作靜態變數或類變數;沒 ...
  • 1. 如何查看一個類及其父類中的所有方法和屬性 答: Ctrl + o 後,顯示當前類的欄位和方法;再按一次,同時顯示父類的欄位和方法,藍色字為父類屬性 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...