爬取酷狗音乐无框架和有框架版

一、bs4 方式爬取酷狗音乐

思路:

  1.  访问要爬的网页 https://www.kugou.com/
  2. 分析网页的内容和特点,确定如何定位到要抓的元素;用chrome自带的开发者工具,选择你要抓取网页的数据来定位其所在的标签
  3. 获取源码
  4. 生成html解析器soup
  5. 用soup.find_all("div")类似用法找到所有想要的标签对象
  6. 通过过滤属性找到需要的div标签
  7. 在div标签下,find_all遍历拿到所有的li标签,li标签对象(包含一个歌曲信息)放到了列表s
  8. 遍历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、执行流程

  1. 创建一个 Scrapy 项目
  2. 引擎从调度器取出一个 URL 用于抓取
  3. 引擎把 URL 封装成一个 Requests 请求然后传给下载器把相应结果下载下来并封装成应答包
  4. 解析应答包
  5. 定义解析规则(Item)
  6. 根据定义规则解析内容后交给实体管道等待处理
  7. 解析出 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 也会重新下载。)

 

 

posted @ 2020-11-04 11:58  hqq的进阶日记  阅读(462)  评论(0编辑  收藏  举报