當前位置:
首頁 > 知識 > 抓取豆瓣音樂Top 250數據存到Excel中

抓取豆瓣音樂Top 250數據存到Excel中

點擊上方

Python開發

」,選擇「置頂公眾號」


關鍵時刻,第一時間送達!



引言:



失蹤人口回歸,最近比較迷茫,不知道是回頭深究Android,還是繼續
學Python,Android是舊愛,Python是新歡;Android應用層折騰來
折騰去,無非:改UI,寫控制項,換下庫,換下架構…以前一直想著寫
自己的項目,然後各種加東西優化,然後發現自己卻沒有了當年的熱情,
唉!相比Python,隨手就是一爬蟲,批處理類的腳本,實用性高太多,
只是Python沒有引路人,都是自己一點點摸索,見步走步吧!





之前在寫爬小姐姐腳本時候,就遇到過一個如何存儲爬取到數據的問題,
比如一個系列的套圖鏈接應該放到特定的文件夾,我之前的操作都是
通過下面這樣的格式寫入到一個txt文件中:目錄~鏈接
然後讀取txt文件,獲得字元串,然後通過split(「~」)來進行分隔,
split(「~」)[0]是目錄,split(「~」)[1]是路徑,挺low的,
如果是涉及到三個維度以上的再拼多一個~,在上上一節抓
半次元coser的時候就遇到一個噁心的問題,符號都他么被用了,
難以分隔,一個個特殊字元試,後面試到Θ才可以..
迫切需要一個東西來存我們抓取到的數據,當然最好用:資料庫
但是考慮到學習成本(主要是我不熟!),先通過一個簡單的東西存起來。





最簡單的肯定是通過Excel表格啊,最直觀了,非編程人員也能看懂!
不多說,開始本節內容~ 本節抓取例子:豆瓣音樂 Top 250
鏈接:https://music.douban.com/top250


1.編寫抓數據腳本


依次校驗:


1.數據能在Network選項卡找到,非JS動態載入,直接處理結果就好


2.點擊第二頁,選中XHR,沒有東東,不是Ajax動態載入


鏈接規則:


第一頁:https://music.douban.com/top250?start=0
第二頁:https://music.douban.com/top250?start=25
第三頁:https://music.douban.com/top250?start=50
鏈接規則顯而易見,每25條一頁,0,25,50,75…225



請求頭:


就一個:Host:music.douban.com
模擬請求的套路摸清了,接下來就是處理網頁拿到想要的數據了:
看下Element,不難發現數據都單獨放在一個個table里:





點開其中一個:





先捋下我們想採集到的數據:
圖片鏈接,歌名,歌手,發行時間,分類,評分,評分人數,歌曲詳情頁,然後就是慢慢摳數據了,自己私下摳,不會摳找以前文章看,這裡直接給出代碼:





看下控制台列印出來的信息:





可以,沒毛病,接下來看下怎麼把數據寫到excel表格里~



2.如何將數據寫入到Excel中


Step 1:安裝庫,操作Excel,你需要兩個庫:xlwt(寫Excel) 和 xlrd(讀Excel)
命令行pip安裝一波。

sudo pip3 install xlwt
sudo pip3 install xlrd

Step 2:熟悉幾個基本函數
寫入Excel:


xlwt.Workbook():創建一個工作薄


工作薄對象.add_sheet(cell_overwrite_ok=True):添加工作表,括弧里是可選
參數,用於確認同一個cell單元是否可以重設值


工作表對象.write(行號,列號,插入數據,風格),第四個參數可選
舉個簡單例子:插入這樣的數據:

sheet.write(

0

,

0

,

"姓名"

)
sheet.write(

0

,

1

,

"學號"

)
sheet.write(

1

,

0

,

"小豬"

)
sheet.write(

1

,

1

,

"No1"

)

得到的表格:





工作薄對象.save(Excel文件名):保存到Excel文件中


讀取Excel:


xlrd.open_workbook():讀取一個Excel文件獲得一個工作薄對象


工作薄對象.sheets()[0]:根據索引獲得工作薄里的一個工作表


工作表對象.nrows:獲得行數


工作表對象.ncols:獲得列數

工作表對象.row_values(pos):讀取某一行的數據,返回結果是列表類型的


3.編寫一個Excel協助類


基本語法了解得差不多了,接著我們來寫一個工具類,來把我們爬蟲
爬取到的數據寫入到Excel表格里,四個方法:


style:

根據傳入的字體名稱,高度,是否加粗,返回一個Style樣式

init:

完成Excel表的一些初始化操作,初始化表頭

insertdata:

把爬取到的數據插入到Excel里的方法

readdata:

讀取Excel里數據的方法



接著一步步來,先是style方法:





接著是__init方法,判斷Excel文件是否存在,不存在則新建並進行初始化





再接著是insert_data:





最後是read_data:





代碼不算複雜,接著寫下調用代碼試試:





加一個列印data_group的方法,看下抓取的數據,運行下:





沒毛病,圈住哪裡[[,這裡想表達結果是一個大列表嵌套多個列表!
再接著添加下述代碼:





執行後可以看到,生成了一個dbyy.xlsx的文件,打開看看:





嘖嘖,寫入成功,美滋滋!
再接著把無關代碼注釋掉,調用下讀取Excel的方法:





讀寫都沒問題,嚶嚶嚶~






4.小結


本節講解了一波如何把爬取到的數據存到Excel表裡,以及讀取Excel表裡的數據,
雖然沒有資料庫高端,但是比起之前用分隔符分隔多中類型的數據,用到的時候
split()好多了,而且非開發者也能直接看懂,除此之外,哪天說不定可以撩到
一些文員小姐姐(編寫批處理Excel表的腳本),除此之外還可以做些詞頻統計類
的腳本玩玩,最後獻上哲♂學啟蒙老師照片來結束本節內容,願天堂沒有摔跤:


附:具體實現代碼(其實都可以在https://github.com/coder-pig/ReptileSomething 找到)

import re
import requests
import xlwt
import xlrd
import tools as t

rate_count_pattern = re.compile(

"(d*人評價)"

, re.S)# 獲取評分人數的正則
base_url =

"https://music.douban.com/top250"

save_file =

"dbyy.xlsx"

# 解析網頁獲得數據的方法
def parse_url(//img.ifuun.com/getimg.php?url=offset):
   resp = requests.get(base_url, params={

"page"

: offset})    
   print(

"解析:"

+ resp.url)    
   result = []
   if resp.status_code ==

200

:
       soup = t.get_bs(resp.content)        
       tables = soup.select(

"table[width="100%%"]"

)
       for table in tables:    
           a = table.find(

"a"

)            
           detail_url = a[

"href"

]# 歌曲詳情頁面
           img_url = a.img[

"src"

]# 圖片url
           music_name = a.img[

"alt"

]# 歌曲名
           p = table.find(

"p"

)            
           data_split = p.get_text().split(

"/"

)            
           singer = data_split[

0

].strip()# 歌手
           public_date = data_split[

1

].strip()            
           category =

""

# 分類
           for data in data_split[

2

:]:      
               category += data.strip() +

"/"

           div = table.find(

"div"

, class_=

"star clearfix"

)            
           score = div.select(

"span.rating_nums"

)[

0

].text# 評分
           rate_count = rate_count_pattern.search(div.select(

"span.pl"

)[

0

].get_text()).group(

0

)# 評分人數
           result.append([img_url, music_name, singer, public_date, category, score, rate_count, detail_url])
    return result
   
   
class ExcelHelper:
   def__init__(self):
      if not t.is_dir_existed(save_file, mkdir=False):
          #

1.

創建工作薄
          self.workbook = xlwt.Workbook()
          #

2.

創建工作表,第二個參數用於確認同一個cell單元是否可以重設值
          self.sheet = self.workbook.add_sheet(u

"豆瓣音樂Top 250"

, cell_overwrite_ok=True)
          #

3.

初始化表頭
          self.headTitles = [u

"圖片鏈接"

,u

"歌名"

,u

"歌手"

,u

"發行時間"

,u

"分類"

,u

"評分"

,u

"評分人數"

,u

"歌曲詳情頁"

]
          for i, item in enumerate(self.headTitles):                
              self.sheet.write(

0

, i, item, self.style(

"Monaco"

,

220

, bold=True))            
          self.workbook.save(save_file)
         
    # 參數依次是:字體名稱,字體高度,是否加粗
    def style(self, name, height, bold=False):
        style = xlwt.XFStyle()# 賦值style為XFStyle(),初始化樣式
        font = xlwt.Font()# 為樣式創建字體樣式
        font.name = name        
        font.height = height        
        font.bold = bold
        return style
       
     # 往單元格里插入數據
     def insert_data(self, data_group):
         

try

:      
             xlsx = xlrd.open_workbook(save_file)# 讀取Excel文件
             table = xlsx.sheets()[

0

]# 根據索引獲得表
             row_count = table.nrows# 獲取當前行數,新插入的數據從這裡開始
             count =

0

             for data in data_group:
                 for i in range(len(data)):              
                     self.sheet.write(row_count + count, i, data[i])                
                 count +=

1

     except Exception as e:        
         print(e)
     

finally

:          
         self.workbook.save(save_file)
         
  # 讀取Excel里的數據
  def read_data(self):
      xlsx = xlrd.open_workbook(save_file)        
      table = xlsx.sheets()[

0

]        
      nrows = table.nrows# 行數
      ncols = table.ncols# 列數
      # 從第一行開始,

0

是表頭
      for i in range(

1

, nrows):
          # 讀取某行數據
          row_value = table.row_values(i)            
          print(row_value)
         

if__name__ ==

"__main__"

:    
  offsets = [xforxinrange(

0

,

250

,

25

)]    
  data_group = []
  for offset in offsets:      
      data_group += parse_url(//img.ifuun.com/getimg.php?url=offset)    
  print(data_group)    
  excel = ExcelHelper()    
  excel.insert_data(data_group)    
  excel.read_data()




  • 作者:簡書-coder_pig



  • https://www.jianshu.com/p/27c2e380d57b



  • Python開發整理髮布,轉載請聯繫作者獲得授權


【點擊成為Java大神】

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發 的精彩文章:

Cython 三分鐘入門
2017 年關於 Python 的 12 件大事

TAG:Python開發 |