爬取酷狗音乐无框架和有框架版
一、bs4 方式爬取酷狗音乐
思路:
- 访问要爬的网页 https://www.kugou.com/
- 分析网页的内容和特点,确定如何定位到要抓的元素;用chrome自带的开发者工具,选择你要抓取网页的数据来定位其所在的标签
- 获取源码
- 生成html解析器soup
- 用soup.find_all("div")类似用法找到所有想要的标签对象
- 通过过滤属性找到需要的div标签
- 在div标签下,find_all遍历拿到所有的li标签,li标签对象(包含一个歌曲信息)放到了列表s
- 遍历s列表中的内容,通过select,get各种方法,拿到每一首三个信息:歌名、链接、歌的长度
补充:
酷狗音乐首页要爬取的代码部分:
![](https://img2020.cnblogs.com/blog/1835832/202011/1835832-20201104112929282-2139269549.png)
代码:
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
![](https://img2020.cnblogs.com/blog/1835832/202011/1835832-20201104113849398-1999202486.png)
生成文件:
![](https://img2020.cnblogs.com/blog/1835832/202011/1835832-20201104113805439-1919478144.png)
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
![](https://img2020.cnblogs.com/blog/1835832/202011/1835832-20201104114456540-1035858110.png)
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 也会重新下载。)