利用Scrapy框架爬取落网上的音乐文件
今天爬取的是本人特别喜欢的一个音乐网站,www.luoo.net,
首先是设置item中需要保存的字段。
items.py
字段名称包括期刊号,期刊名,期刊创建时间,单期期刊下的音乐名,作者名,音乐文件url,文件下载结果。
1 import scrapy 2 3 4 class LuoWangSpiderItem(scrapy.Item): 5 vol_num = scrapy.Field() 6 vol_title = scrapy.Field() 7 vol_time = scrapy.Field() 8 music_name = scrapy.Field() 9 music_author = scrapy.Field() 10 music_urls = scrapy.Field() 11 music_files = scrapy.Field()
接下来我的爬虫文件。
luowang.py
该模块需要的注意的地方可能就是期刊号和期刊名称是单一值,每个期刊下面都有十几首歌曲,需要将获取的url添加到一个url列表中,在最终形成一个music_urls字段,music_author字段同理。
然后,当进入期刊详情页的时候,期刊中的歌曲是自动播放或点击url播放,对于这种动态加载的过程,我是进入network查看音乐的真是url,然后通过拼接url,得到最终每首歌曲的url,保存在music_urls中,稍后等待Pipelines中的FilesPipeline类发送请求。
1 # -*- coding: utf-8 -*- 2 import scrapy 3 from LuoWangSpider.items import LuoWangSpiderItem 4 5 6 class LuowangSpider(scrapy.Spider): 7 name = 'luowang' 8 allowed_domains = ['luoo.net'] 9 offset = 1 10 url = 'http://www.luoo.net/tag/?p=' 11 # 字符串拼接出起始页的url 12 start_urls = [url + str(offset)] 13 14 def parse(self, response): 15 vol_list = response.xpath("//div[@class='vol-list']/div/a/@href").extract() 16 total_page = response.xpath("//div[@class='paginator']/a[12]/text()").extract()[0] 17 18 for vol in vol_list: 19 yield scrapy.Request(url=vol, callback=self.parse_1) 20 21 # 字符串拼接出所有分页的url 22 self.offset += 1 23 if self.offset < int(total_page): 24 url = self.url + str(self.offset) 25 yield scrapy.Request(url=url, callback=self.parse) 26 27 def parse_1(self , response): 28 # 进入到期刊详情页 29 30 item = LuoWangSpiderItem() 31 item['vol_num'] = response.xpath("//div[@class='container ct-sm']/h1/span[1]/text()").extract()[0] 32 item['vol_title'] = response.xpath("//div[@class='container ct-sm']/h1/span[2]/text()").extract()[0] 33 item['vol_time'] = response.xpath("//div[@class='clearfix vol-meta']/span[2]/text()").extract()[0] 34 35 music_list = response.xpath("//*[@id='luooPlayerPlaylist']/ul/li") 36 # vol系列字段为单一值,music系列字段为列表 37 music_name_list = [] 38 music_author_list = [] 39 music_url_list = [] 40 for music in music_list: 41 music_name = music.xpath('./div/a[1]/text()').extract()[0] 42 music_author = music.xpath('./div/span[2]/text()').extract()[0] 43 music_name_list.append(music_name) 44 music_author_list.append(music_author) 45 46 item['music_author'] = music_author_list 47 item['music_name'] = music_name_list 48 49 # 由于该页面为js动态加载,通过抓包得到文件url,利用期刊号加音乐编号,拼接url 50 for j in item['music_name']: 51 music_url = 'http://mp3-cdn2.luoo.net/low/luoo/radio' + item['vol_num'] + '/' + str(j[0:2]) + '.mp3' 52 music_url_list.append(music_url) 53 item['music_urls'] = music_url_list 54 55 response.meta['item'] = item 56 57 yield item
pipelines.py
管道文件,创建一个继承于FilesPipeline的类,改写item_completed方法和file_path方法,用来自定义文件下载路径和和给文件重命名。
值得注意的有的时候程序不报错但是也没有按照预期来执行下载,我们就可以打印results,这是get_media_request方法发送请求回来的响应结果。
# -*- coding: utf-8 -*- import os import json import scrapy from scrapy.exceptions import DropItem from settings import FILES_STORE from scrapy.pipelines.files import FilesPipelineclass Mp3Pipeline(FilesPipeline):'''自定义文件下载管道'''def get_media_requests(self, item, info):'''根据文件的url逐一发送请求:param item: :param info: :return: '''for music_url in item['music_urls']:yield scrapy.Request(url=music_url, meta={'item':item})def item_completed(self, results, item, info):'''处理请求结果:param results: :param item: :param info: :return: '''print results,'RRRRRRRRRRRRRRRRRRRRRRR'file_paths = [x['path'] for ok, x in results if ok]if not file_paths:raise DropItem("Item contains no files")for i in range(0, len(item['music_name'])):old_name = FILES_STORE + file_paths[i]new_name = FILES_STORE + 'Vol.' + item['vol_num'] + '_' + item['vol_title'] + '/' + item['music_name'][i] + '.mp3'# 文件重命名 os.rename(old_name, new_name) return itemdef file_path(self, request, response=None, info=None):'''自定义文件保存路径:param request::param response::param info::return:'''vol_title = request.meta['item']['vol_title']vol_num = request.meta['item']['vol_num']file_name = request.url.split('/')[-1]folder_name = 'Vol.' + vol_num + '_' + vol_titlereturn '%s/%s' % (folder_name, file_name)# # 将文本文件保存为json格式 # class LuoWangSpiderPipeline(object): # def __init__(self): # self.json_file = open(r'F:\luowang\luowang.json', 'wb') # # def process_item(self, item, spider): # self.json_file.write(json.dumps(dict(item),ensure_ascii=False) + '\n') # return item
settings.py
以下是settings文件,只包含部分代码。
1 FILES_STORE = 'F:/luowang/' 2 # 文件url保存在item中的字段 3 FILES_URLS_FIELD = 'music_urls' 4 # 文件的结果保存在item中的字段 5 FILES_RESULT_FIELD = 'music_files' 6 7 ITEM_PIPELINES = { 8 # 'LuoWangSpider.pipelines.LuoWangSpiderPipeline': 200, 9 # 'scrapy.pipelines.files.FilesPipeline': 300, 10 'LuoWangSpider.pipelines.Mp3Pipeline': 1,
最终效果:
源码:
https://github.com/evolution707/LuoWangSpider
转载于:https://www.cnblogs.com/zhujunzoe/p/8946923.html
利用Scrapy框架爬取落网上的音乐文件相关推荐
- python爬虫利用Scrapy框架爬取汽车之家奔驰图片--实战
先看一下利用scrapy框架爬取汽车之家奔驰A级的效果图 1)进入cmd命令模式下,进入想要存取爬虫代码的文件,我这里是进入e盘下的python_spider文件夹内 C:\Users\15538&g ...
- 利用Scrapy框架爬取LOL皮肤站高清壁纸
利用Scrapy框架爬取LOL皮肤站高清壁纸 Lan 2020-03-06 21:22 81 人阅读 0 条评论 成品打包:点击进入 代码: 爬虫文件 # -*- coding: utf- ...
- 利用Scrapy框架爬取前途无忧招聘信息
利用Scrapy框架爬取前途无忧招聘信息 关于安装和命令使用可参考:https://docs.scrapy.org/en/1.7/intro/install.html 先创建项目和爬虫文件 分析网站 ...
- python笔记之利用scrapy框架爬取糗事百科首页段子
环境准备: scrapy框架(可以安装anaconda一个python的发行版本,有很多库) cmd命令窗口 教程: 创建爬虫项目 scrapy startproject qq #创建了一个爬虫项目q ...
- 利用scrapy框架爬取动态加载的数据
在爬取有些网站的是后,数据不一定全部是可视化界面的,当我们拖动滚动条时才会加载其他的数据,如果我们也想爬取这部分数据,就需要使用selenium模块,在scrapy里可以结合该模块修改返回对象 一.编 ...
- 利用Scrapy框架爬取汽车之家图片(详细)
爬取结果 爬取步骤 创建爬虫文件 进入cmd命令模式下,进入想要存取爬虫代码的文件,我这里是进入e盘下的E:\pystudy\scraping文件夹内 C:\Users\wei>E:E:\> ...
- 利用scrapy框架爬取网易新闻排行榜
wyxw.py中代码 # -*- coding: utf-8 -*- import scrapy from ..items import WyxwItemclass WyxwSpider(scrapy ...
- Python爬虫实战之利用Scrapy框架爬取传智播客课程数据
1.文件结构: 2.lesson.py代码 import scrapy from ts.items import TsItem from scrapy.http import Requestclass ...
- 利用python的scrapy框架爬取google搜索结果页面内容
scrapy google search 实验目的 爬虫实习的项目1,利用python的scrapy框架爬取google搜索结果页面内容. https://github.com/1012598167/ ...
最新文章
- FBI发警告:留意联网汽车被黑客攻击风险
- QML编程之旅 -- 元素布局
- 大型网站系统架构系列:负载均衡详解(一)
- 文献学习(part78-A)--A Survey of Clustering Algorithms for Big Data: T axonomy Empirical Analysis
- 前端学习(2776):组件的生命周期和过程
- 顺序程序设计03 - 零基础入门学习C语言09
- java返回类型自动_java-Apache Flink:由于类型擦除,无法自动确定函数的返回类型...
- 大数据之-Hadoop3.x_MapReduce_ReduceTask工作机制并行度---大数据之hadoop3.x工作笔记0125
- [CQOI2016]手机号码
- 190221每日一句
- 自动驾驶的Pipline -- 如何打造自动驾驶的数据闭环?(下)
- from PyQt4 import QtGui,QtCore出错
- 手机如何安装java软件_如何在手机上安装JAVA平台
- 对抗Windows Defender的方法和思路
- 【latex入门】基本语法|常见报错
- 咖啡,为什么有些比较甜?
- HTML5 之 Figure Figcaption 标签
- ubuntu 17\18.04 调节鼠标指针速度
- LZO--实时数据压缩库
- Java Web 回顾-HCJ
热门文章
- Java并发编程之Java线程池
- request.META里包含了哪些数据?
- 请概述可视化卷积神经网络的中间输出的基本思想。_万字长文:特征可视化技术(CAM)...
- nodejs实践录:开篇
- 【Kafka】KIP-285 Connect Rest Extension Plugin kafka 连接 rest 的插件
- 【java】序列化:ProtoBuf 与 JSON 的比较
- 【算法】赫夫曼编码 解码 实际应用 文件的编码 解码
- 95-36-220-ChannelHandler-RejectedExecutionHandlers
- 【ElasticSearch】Es 源码之 NodeConnectionsService 源码解读
- 【Java】开源工具 Hutool 不糊涂