爬取酷狗音樂無框架和有框架版
一、bs4 方式爬取酷狗音樂
思路:
- 訪問要爬的網頁 https://www.kugou.com/
- 分析網頁的內容和特點,確定如何定位到要抓的元素;用chrome自帶的開發者工具,選擇你要抓取網頁的數據來定位其所在的標簽
- 獲取源碼
- 生成html解析器soup
- 用soup.find_all("div")類似用法找到所有想要的標簽對象
- 通過過濾屬性找到需要的div標簽
- 在div標簽下,find_all遍歷拿到所有的li標簽,li標簽對象(包含一個歌曲信息)放到了列表s
- 遍歷s列表中的內容,通過select,get各種方法,拿到每一首三個信息:歌名、鏈接、歌的長度
補充:
酷狗音樂首頁要爬取的代碼部分:
代碼:
1 #coding=utf-8 2 import requests,urllib 3 from bs4 import BeautifulSoup 4 import os 5 6 result=urllib.request.urlopen("http://www.kugou.com")#發出請求 7 8 soup=BeautifulSoup(result.read(),'html.parser')#生成可分析對象 9 for i in soup.find_all("div"):#遍歷所有div標簽 10 if i.get("id")=="SongtabContent":#判斷id為SongtabContent的div標簽 11 s=i.find_all("li")#把所有li標簽內容賦值給s變量 12 13 with open(r"D://music.txt","w",encoding="utf-8") as f:#創建要寫入文件對象 14 for i in s:#遍歷所有li標簽對象 15 f.write("歌曲名稱為: %s "%i.a.select(".songName")[0].text)#獲取class為songName的值 16 f.write("歌曲播放連接為: %s "% i.a.get("href")) #獲取標簽為href的值 17 f.write("歌曲播放時間為: %s" %i.a.select(".songTime")[0].text) #獲取class為songTime的值 18 f.write(os.linesep)
爬取結果:

二、使用 scrapy 框架爬取酷狗音樂
1、命令1:
scrapy startproject groad

生成文件:

2、命令2:
scrapy genspider newsong www.kugou.com
生成文件:

3、修改文件
1)修改 setting.py 文件:設置爬蟲優先級
ITEM_PIPELINES = { 'groad.pipelines.GroadPipeline': 300, }
2)修改 items.py 文件:定義變量,變量用于存儲從網頁提取的數據。
定義的是你要存儲的數據格式,這個格式叫做item
聲明一些變量,用于存儲抓取的數據
import scrapy class GroadItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() # 定義項目的字段 songName = scrapy.Field() #歌曲名稱 songTime = scrapy.Field() #歌曲播放時間 href_song = scrapy.Field()#歌曲播放連接
3)修改 pipelines.py 文件:將網頁提取出來的數據保存item數據
import json class GroadPipeline(object): def __init__(self): self.filename = open("D://test//groad//groad//spiders//newsong.txt", "w",encoding="utf-8") def process_item(self, item, spider): text = json.dumps(dict(item),ensure_ascii=False)+'\n' self.filename.write(text) return item def close_spider(self, spider): self.filename.close()
4)修改 newsong.py 文件:爬蟲的主要邏輯
import scrapy from groad.items import GroadItem class NewsongSpider(scrapy.Spider): name = 'newsong' allowed_domains = ['www.kugou.com'] start_urls = ['http://www.kugou.com/'] def parse(self, response): #response 框架自動將響應對象的源碼傳入 item=GroadItem() for i in range(1,len(response.xpath('//*[@id="SongtabContent"]/ul'))+1): for j in range(1,len(response.xpath('//*[@id="SongtabContent"]/ul[%s]/li' % i))+1): item['songName'] = response.xpath('//*[@id="SongtabContent"]/ul[%s]/li[%s]/a/span[1]/text()' % (i,j)).extract()[0] #extract()取到的是列表,只有一個值 item['songTime'] = response.xpath('//*[@id="SongtabContent"]/ul[%s]/li[%s]/a/span[@class="songTime"]/text()' % (i, j)).extract()[0] item['href_song'] = response.xpath('//*[@id="SongtabContent"]/ul[%s]/li[%s]/a/@href' % (i, j)).extract()[0] yield item #item發送給pipeline.py讓這個文件去保存抓到的數據 #抓到一首歌的數據類似:{"songName":"xxxxxx","songTime":"yyyyyy","href_song"="zzzzzzzzz"}發給pipeline.py保存
4、執行命令爬取:在工程目錄下
scrapy crawl newsong
5、爬取結果


三、Scrapy 原理
1、執行流程
- 創建一個 Scrapy 項目
- 引擎從調度器取出一個 URL 用于抓取
- 引擎把 URL 封裝成一個 Requests 請求然后傳給下載器把相應結果下載下來并封裝成應答包
- 解析應答包
- 定義解析規則(Item)
- 根據定義規則解析內容后交給實體管道等待處理
- 解析出 URL 交給調度器繼續等待被抓取
2、運作流程
代碼寫好,程序開始運行... 1 引擎:Hi!Spider, 你要處理哪一個網站? 2 Spider:老大要我處理 xxxx.com。 3 引擎:你把第一個需要處理的 URL 給我吧。 4 Spider:給你,第一個 URL 是 xxxxxxx.com。 5 引擎:Hi!調度器,我這有 request 請求你幫我排序入隊一下。 6 調度器:好的,正在處理你等一下。 7 引擎:Hi!調度器,把你處理好的 request 請求給我。 8 調度器:給你,這是我處理好的 request 9 引擎:Hi!下載器,你按照老大的下載中間件的設置幫我下載一下這個 request 請求 10 下載器:好的!給你,這是下載好的東西。(如果失敗:sorry,這個 request 下載失敗了。然后引擎告訴調度器,這個 request 下載失敗了,你記錄一下,我們待會兒再下載) 11 引擎:Hi!Spider,這是下載好的東西,并且已經按照老大的下載中間件處理過了,你自己處理一下(注意!這兒 responses 默認是交給 def parse()這個函數處理的) 12 Spider:(處理完畢數據之后對于需要跟進的 URL),Hi!引擎,我這里有兩個結果,這個是我需要跟進的 URL,還有這個是我獲取到的 Item 數據。 13 引擎:Hi !管道 我這兒有個 item 你幫我處理一下!調度器!這是需要跟進 URL 你幫我處理下。然后從第四步開始循環,直到獲取完老大需要全部信息。 14 管道調度器:好的,現在就做! 注意!只有當調度器中不存在任何 request 了,整個程序才會停止,(也就是說,對于下載失敗的 URL,Scrapy 也會重新下載。)
浙公網安備 33010602011771號