本
文
摘
要
通过前七章的学习,相信大家对整个爬虫有了一个比较全面的了解 ,其中分别涉及四个案例:静态网页爬取、动态Ajax网页爬取、Selenium浏览器模拟爬取和Fillder今日头条app爬取,基本涵盖了爬虫的大致套路。本文在此基础上进一步深耕,使用Scrapy框架构建QQ音乐分布式爬虫系统,更加接近搜索引擎技术。
一、前期准备
1.Scrapy原理概述
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。其最初是为了爬虫或者数据采集所设计的, 也可以应用在获取API所返回的数据或者通用的网络爬虫。简单来说,与普通爬虫相比,Scrapy“有组织 有纪律”,更容易构建大规模抓取项目。
下图即为Scrapy框架的原理架构图,下面来一一解释:
Engine:引擎,框架的核心,用于触发事务,处理整个系统的数据流处理。(Scrapy已实现)Spiders:即爬虫主程序,定义了爬取的逻辑和网页内容的解析规则,主要负责解析响应并生成结果和新的请求(需要自己编写)Scheduler:任务调度器,接受引擎发过来的请求并将其加入队列中,在引擎再次请求时将请求提供给引擎。(需要自己编写)Downloader:下载器,下载网页内容,并将下载内容返回给spider进行处理(Scrapy已实现)ItemPipeline:项目管道,负责处理spider从网页中抽取的数据,主要是负责清洗,验证和向数据库中存储数据(需要自己编写)Downloader Middlewares:下载中间件,是处于Scrapy的Request和Requesponse之间的处理模块(Scrapy已实现)Spider Middlewares:spider中间件,主要处理spider输入的响应和输出的结果及新的请求middlewares.py里实现(Scrapy已实现)有了上文对Scrapy组件的介绍,下面描述一下Scrapy运作流程:
Spider使用yeild将request发送给EngineEngine对request不做任何处理发送给SchedulerEngine拿到request,通过Middleware发送给DownloaderDownloader获取response之后经过Middleware发送给EngineEngine传递给Spider,Spider的parse()方法对response进行解析Spider将解析出来的items或者requests返回给EngineEngine将items发送给ItemPipeline,将requests发送给Scheduler只有当Scheduler中不存在request时程序才会停止2.Scrapy安装配置
接下来开始安装Scrapy,Scrapy已经支持python3,本文环境为win10+Anaconda3,实测安装没有出现问题。首先通过pip安装Scrapy:
pip install scrapy之后进入到python命行并导入,如果没有出现报错则初步说明安装成功。
import scrapy3.Scrapy入门测试
接着我们通过一个百度分布式爬虫框架小例子进行测试,首先在cmd中用cd命令切到任一目录,之后运行:
scrapy startproject littletest然后切换至项目目录并通过genspider命令加入爬虫网站:
cd littletest scrapy genspider baidu www.baidu.com之后进入目录查看,目录结构如下:
scrapy. cfg # Scrapy 部署时的配置文件littletest #项目模块items.py # 定义爬取的数据结构middlewares.py # 定义爬取时的中间件pipelines.py # Pipelines 的定义,定义数据管道settings.py #配置文件,放置基本设置和存储变量spiders #放置Spiders 的文件夹同时我们进入settings.py将ROBOTSTXT_OBEY配置项改为False,即不遵守爬虫协议,否则很多网站无法正常获取。
ROBOTSTXT_OBEY = False最后进入命令行启动scrapy爬虫:
scrapy crawl baidu得到结果如下,状态码为200且接收字节数大于0,则表明爬取成功!
3.MongDB安装配置
MongoDB 是目前最流行的 NoSQL 数据库之一,使用的数据类型 BSON(类似 JSON),下载安装及配置以及链接python的pymongo数据库和最优秀的compass可视化工具安装及使用可参考作者博客。
二、QQ音乐爬虫实战
1.网页分析
通过打开QQ音乐官网并点击歌手栏(链接传送门:
https://y.qq.com/portal/singer_list.html),并打开DevTools工具,选择XHR异步并观察item,发现musicu.fcg一栏返回的json数据中有歌手相关信息。因此我们进一步进入该项headers获取到请求url,继续点击下一页,通过三页(url如下)查找规律进一步发现sin参数发生变化,规律公式为80*(n-1),n为页码。篇幅有限,json数据解析就不再解释,可参考前文。
https://u.y.qq.com/cgi-bin/musicu.fcg?-=getUCGI9874589974344781&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A0%2C%22cur_page%22%3A1%7D%7D%7D https://u.y.qq.com/cgi-bin/musicu.fcg?-=getUCGI8205866038561849&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A80%2C%22cur_page%22%3A2%7D%7D%7D https://u.y.qq.com/cgi-bin/musicu.fcg?-=getUCGI8189152987042585&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A160%2C%22cur_page%22%3A3%7D%7D%7D以此类推依次获取到歌曲下载地址、歌曲列表地址、歌词列表地址、歌曲评论地址等并配置翻页参数:
start_urls = [https://u.y.qq.com/cgi-bin/musicu.fcg?data=%7B%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer \ %22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genr \ e%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A{num}%2C%22cur_page%22%3A{id}%7D%7D%7D] # 歌手地址 song_down = https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?&jsonpCallback=MusicJsonCallback&ci \ d=205361747&songmid={songmid}&filename=C400{songmid}.m4a&guid=9082027038 # 歌曲下载地址 song_url = https://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg?singermid={singer_mid}&order=listen&num={sum} # 歌曲列表地址 lrc_url = https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric.fcg?nobase64=1&musicid={musicid} # 歌词列表地址 discuss_url = https://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg?cid=205360772&reqtype=2&biztype=1&topid= \ {song_id}&cmd=8&pagenum=0&pagesize=25 # 歌曲评论地址之后我们开始建立scrapy爬虫程序。首先切换至个人目录下面开启项目:
scrapy startproject musicspyder cd musicspyder scrapy genspider qqmusic y.qq.com2.spyder.py编写
接下来开始对Scrapy组件逐一完善,首先对主要爬虫程序qqmusic.py进行编写,在生成类中分别定义爬虫名、允许域名、爬取url等变量,并创建解析用户信息、歌曲信息、歌词信息、评论信息、url信息方法:
import json import scrapy from scrapy import Request from musicspyder.items import QqMusicItem class MusicSpider(scrapy.Spider): name = qqmusic allowed_domains = [y.qq.com] start_urls = [...] song_down = ... song_url = ... lrc_url = ... discuss_url = ... # 生成请求并从配置中获取页数 def start_requests(self): # 解析用户信息 def parse_user(self, response) # 解析歌曲信息 def parse_song(self, response) # 解析歌词信息 def parse_lrc(self, response) # 解析评论信息 def parse_comment(self, response) # 解析url信息 def parse_url(self, response)3.items.py编写
之后对items.py进行编写,在QqMusicItem类中创建MongoDB *** 名、id字段、歌手名字段、歌曲名字段、歌曲地址字段、歌词字段、评论字段等变量:
import scrapy from scrapy import Field class QqMusicItem(scrapy.Item): # mongodb collection collection = singer id = Field() # 歌手名字字段 singer_name = Field() # 歌曲名字段 song_name = Field() # 歌曲地址字段 song_url = Field() # 歌词字段 lrc = Field() # 评论字段 comment = Field()4.piplines.py编写
再对piplines.py进行编写,新增加IrcText类对歌词进行解析处理:
import json import pymongo import re from scrapy.exceptions import DropItem from musicspyder.items import QqMusicItem # 默认pipline类 class QqMusicPipeline(object): def process_item(self, item, spider): return item # 在pipline中新增类用于解析和清洗单词 class lrcText(object): # 进行正则匹配获取的单词 def process_item(self, item, spider): # 保存到Mongo数据库 class MongoPipline(object): # 构造方法 def __init__(self, mongo_url, mongo_db): # 从settings.py中获取Mongo rl和库 @clas *** ethod def from_crawler(cls, crawler): # 存储处理 def process_item(self, item, spider): # 关闭mongodb数据库 def close_spider(self, spider):之后是middlewares.py代码编写,自定义my_useragent类,使用random库随机选择浏览器头:
import random from scrapy import signals # 默认中间件 class MusicspyderSpiderMiddleware(object): @clas *** ethod def from_crawler(cls, crawler): def process_spider_input(self, response, spider): def process_spider_output(self, response, result, spider): def process_spider_exception(self, response, exception, spider): def process_start_requests(self, start_requests, spider): def spider_opened(self, spider): # 在中间件中加入useragent防爬 class my_useragent(object): def process_request(self, request, spider): user_agent_list = [...,...,...] user_agent = random.choice(user_agent_list) request.headers[User_Agent] = user_agent6.settings.py编写
最后是settings.py编写,配置相应的爬取页数、爬取歌手歌曲数量、mongoDB的地址与数据库等变量,并且设置不遵守Robots协议,开启下载中间件和itempipline:
# 系统配置变量 BOT_NAME = musicspyder SPIDER_MODULES = [musicspyder.spiders] NEWSPIDER_MODULE = musicspyder.spiders MAX_PAGE = 3 # 爬取页数 SONGER_NUM = 1 # 爬取歌手歌曲数量 MONGO_URL = mongodb://localhost:27017/ MONGO_DB = music # mongo数据库 # 定义robots协议遵守规则为:不遵守 ROBOTSTXT_OBEY = False # 启用下载中间件 DOWNLOADER_MIDDLEWARES = { # musicspyder.middlewares.QqMusicDownloaderMiddleware: 543, musicspyder.middlewares.my_useragent: 544, } # 启用pipline中mongodb存储 ITEM_PIPELINES = { # musicspyder.pipelines.QqMusicPipeline: 300, musicspyder.pipelines.lrcText: 300, musicspyder.pipelines.MongoPipline: 302, }定义上述scrapy组件完成之后我们即可在命令行中输入以下命令用以启用qqmusic爬虫框架:
scrapy crawl qqmusic之后进入mongodb查看爬取结果即可得到响应歌手歌曲信息:
三、爬虫系列总结
至此Scrapy框架爬取QQ音乐讲解完成,Python网络爬虫数据采集实战系列也随之结束,总体来说,爬虫是一种细致活,需要掌握固定的套路并且去努力寻找网络数据规律的蛛丝马迹方能爬取成功,同时也要量力而行,防止对对方服务器造成巨大负载或者己方投入产出不成正比。完整代码可以在头条号中私信“QQ音乐”获得,前文涉及的基础知识可参考下面链接:
爬虫所要了解的基础知识,这一篇就够了!Python网络爬虫实战系列
一文带你深入了解并学会Python爬虫库!从此数据不用愁
Python爬虫有多简单?一文带你实战豆瓣电影TOP250数据爬取!
一文弄清Python网络爬虫解析库!内含多个实例讲解
谁说同花顺很难爬?一文带你学会用Python爬取财经动态网页!
谁说京东商品很难爬?一文教你用Python构建电商网站爬虫!
Python网络爬虫实战之Fiddler抓包今日头条app!附代码
参考链接:
https://blog.csdn.net/qq_1290259791/article/details/82263014
https://www.jianshu.com/p/cecb29c04cd2
https://cuiqingcai.com/4380.html