Python分佈式爬蟲一點也不難!Scrapy+MongoDB爬取QQ音樂實戰

通過前七章的學習,相信大家對整個爬蟲有了一個比較全面的瞭解 ,其中分別涉及四個案例:

靜態網頁爬取動態Ajax網頁爬取Selenium瀏覽器模擬爬取Fillder今日頭條app爬取,基本涵蓋了爬蟲的大致套路。本文在此基礎上進一步深耕,使用Scrapy框架構建QQ音樂分佈式爬蟲系統,更加接近搜索引擎技術。

Python分佈式爬蟲一點也不難!Scrapy+MongoDB爬取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已實現)
Python分佈式爬蟲一點也不難!Scrapy+MongoDB爬取QQ音樂實戰

有了上文對Scrapy組件的介紹,下面描述一下Scrapy運作流程:

  1. Spider使用yeild將request發送給Engine
  2. Engine對request不做任何處理發送給Scheduler
  3. Engine拿到request,通過Middleware發送給Downloader
  4. Downloader獲取response之後經過Middleware發送給Engine
  5. Engine傳遞給SpiderSpider的parse()方法對response進行解析
  6. Spider將解析出來的items或者requests返回給
    Engine
  7. Engine將items發送給ItemPipeline,將requests發送給Scheduler
  8. 只有當Scheduler中不存在request時程序才會停止

2.Scrapy安裝配置

接下來開始安裝Scrapy,Scrapy已經支持python3,本文環境為win10+Anaconda3,實測安裝沒有出現問題。首先通過pip安裝Scrapy:

<code>pip install scrapy/<code>

之後進入到python命行並導入,如果沒有出現報錯則初步說明安裝成功。

<code>import scrapy/<code>

3.Scrapy入門測試

接著我們通過一個百度分佈式爬蟲框架小例子進行測試,首先在cmd中用cd命令切到任一目錄,之後運行:

<code>scrapy startproject littletest/<code>

然後切換至項目目錄並通過genspider命令加入爬蟲網站:

<code>cd littletest
scrapy genspider baidu www.baidu.com/<code>

之後進入目錄查看,目錄結構如下:

  • scrapy. cfg # Scrapy 部署時的配置文件
  • littletest #項目模塊
  • items.py # 定義爬取的數據結構
  • middlewares.py # 定義爬取時的中間件
  • pipelines.py # Pipelines 的定義,定義數據管道
  • settings.py #配置文件,放置基本設置和存儲變量
  • spiders #放置Spiders 的文件夾
Python分佈式爬蟲一點也不難!Scrapy+MongoDB爬取QQ音樂實戰

同時我們進入settings.pyROBOTSTXT_OBEY配置項改為False,即不遵守爬蟲協議,否則很多網站無法正常獲取。

<code>ROBOTSTXT_OBEY = False/<code>

最後進入命令行啟動scrapy爬蟲

<code>scrapy crawl baidu/<code>

得到結果如下,狀態碼為200且接收字節數大於0,則表明爬取成功!

Python分佈式爬蟲一點也不難!Scrapy+MongoDB爬取QQ音樂實戰

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數據中有歌手相關信息。

Python分佈式爬蟲一點也不難!Scrapy+MongoDB爬取QQ音樂實戰

因此我們進一步進入該項headers獲取到請求url,繼續點擊下一頁,通過三頁(url如下)查找規律進一步發現sin參數發生變化,規律公式為80*(n-1)n為頁碼。篇幅有限,json數據解析就不再解釋,可參考前文。

<code>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/<code>

以此類推依次獲取到歌曲下載地址歌曲列表地址歌詞列表地址歌曲評論地址等並配置翻頁參數:

<code>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' # 歌曲評論地址/<code>

之後我們開始建立scrapy爬蟲程序。首先切換至個人目錄下面開啟項目:

<code>scrapy startproject musicspyder
cd musicspyder
scrapy genspider qqmusic y.qq.com/<code>

2.spyder.py編寫

接下來開始對Scrapy組件逐一完善,首先對主要爬蟲程序qqmusic.py進行編寫,在生成類中分別定義爬蟲名允許域名爬取url等變量,並創建解析用戶信息歌曲信息歌詞信息評論信息url信息方法:

<code>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)/<code>

3.items.py編寫


之後對items.py進行編寫,在QqMusicItem類中創建MongoDB集合名id字段、歌手名字段、歌曲名字段、歌曲地址字段、歌詞字段、評論字段等變量:

<code>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()/<code>

4.piplines.py編寫


再對piplines.py進行編寫,新增加IrcText類對歌詞進行解析處理:

<code>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和庫
@classmethod

def from_crawler(cls, crawler):
# 存儲處理
def process_item(self, item, spider):
# 關閉mongodb數據庫
def close_spider(self, spider):/<code>

之後是middlewares.py代碼編寫,自定義my_useragent類,使用random庫隨機選擇瀏覽器頭:

<code>import random
from scrapy import signals
# 默認中間件
class MusicspyderSpiderMiddleware(object):
@classmethod
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_agent/<code>

6.settings.py編寫

最後是settings.py編寫,配置相應的爬取頁數爬取歌手歌曲數量、mongoDB的地址

數據庫等變量,並且設置不遵守Robots協議,開啟下載中間件和itempipline:

<code># 系統配置變量
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,
}/<code>

定義上述scrapy組件完成之後我們即可在命令行中輸入以下命令用以啟用qqmusic爬蟲框架:

<code>scrapy crawl qqmusic/<code>

之後進入mongodb查看爬取結果即可得到響應歌手歌曲信息:

Python分佈式爬蟲一點也不難!Scrapy+MongoDB爬取QQ音樂實戰


三、爬蟲系列總結

至此Scrapy框架爬取QQ音樂講解完成,Python網絡爬蟲數據採集實戰系列也隨之結束,總體來說,爬蟲是一種細緻活,需要掌握固定的套路並且去努力尋找網絡數據規律的蛛絲馬跡方能爬取成功,同時也要量力而行,防止對對方服務器造成巨大負載或者己方投入產出不成正比。完整代碼可以在頭條號中私信“QQ音樂”獲得,前文涉及的基礎知識可參考下面鏈接:

參考鏈接:

https://blog.csdn.net/qq_1290259791/article/details/82263014

https://www.jianshu.com/p/cecb29c04cd2

https://cuiqingcai.com/4380.html


分享到:


相關文章: