1. 程式人生 > >用Python爬取使用者蝦米音樂的歌單

用Python爬取使用者蝦米音樂的歌單

Python的爬蟲非常簡單,現在又有成熟的爬蟲框架scrapy。現在,我們來用scrapy爬取自己蝦米歌單上的歌曲。
通過這篇部落格,你將學到:

  1. 基本的爬蟲設計
  2. 模擬登陸
  3. 維持登陸狀態
  4. Xpath

(中的一點皮毛233)。本文預設讀者已經通過scrapy官方文件中文版安裝好了,並試過了測試用例。
然後第一步建立專案:scrapy startproject xiami命令會在當前路徑下建立名為xiami的scrapy專案。

基本的爬蟲設計

從需求的角度出發,先想好我們要爬取的內容,簡單一點的話就爬取網頁的標題、使用者的名字、歌單的歌名。行文順序參照scrapy官方文件的習慣。

items

  先來修改items.py檔案。items是儲存資料的容器,它是scrapy框架自己的資料結構,與字典類似,都是鍵-值對的形式儲存資料。定義了items,我們就可以用scrapy的方式儲存資料到各種資料庫或者本地檔案。將來我們要把爬取到的歌單儲存到本地的json檔案中。

開啟item.py檔案,預設程式碼如下:
# -*- coding: utf-8 -*-

# Define here the models for your scraped items
# ...

import scrapy


class XiamiItem(scrapy.Item):
    # define the fields for your item here like:
# name = scrapy.Field() pass
新增變數初始化
class XiamiItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()  # 網頁的標題
    name = scrapy.Field()  # 使用者的名字
    song = scrapy.Field()  # 歌單的歌名
    pass

這裡我們相當於只是建立了一個空的字典,然後定義了裡面的鍵值。下面我們需要定義爬蟲爬取資料,並把資料交付給items。

spider

當前專案下的spider資料夾下只有一個空的__init__.py檔案。該資料夾負責容納自定義的爬蟲模組。在spider資料夾下建立一個py檔案,就是一個爬蟲模組,當然它現在還沒有任何的功能。建立python file——xiami_spider.py,這就是我們用來爬取蝦米歌單的爬蟲了。然後定義它的基本元素

from scrapy.spiders import CrawlSpider, Rule

class XiamiSpider(CrawlSpider):
    name = "xiaoxia"  # 爬蟲名:小蝦
    allowed_domains = ["xiami.com"]
    start_urls = [
        "http://www.xiami.com"
    ]
    account_number = '9839****[email protected]'  # 換上你的賬號
    password = '123456'  # 換上你的密碼

    # 重寫了start_request方法,Spider類不會再自動呼叫該方法來為start_url中的url建立Request
    def start_requests(self):
        return [Request("https://login.xiami.com/member/login",
                        meta={'cookiejar': 1},
                        callback=self.post_login)]
  • 在這個新建的類中,我們繼承的是CrawlSpider而不是普通的Spider,CrawlSpider是Spider的子類,所以它會有更多的功能,這樣可以少些很多程式碼。
  • 定義了爬蟲的名字,最後在執行程式的時候,需要用到這個名字。
  • 定義了爬取區域的大小。如果不講範圍限制在蝦米網站的網頁中,爬蟲如果不停地最終網頁中的新連結的話,可能會爬取到很多無關網站的無關內容
  • 定義了初始的URL,對spider來說,爬取的迴圈類似下文:
    • 呼叫預設start_requensts()函式,以初始的URL初始化Request並設定回撥函式。 當該request下載完畢並返回時,將生成response,並作為引數傳給該回調函式。spider中初始的request是通過呼叫 start_requests() 來獲取的。 start_requests() 讀取 start_urls 中的URL, 並以 parse 為回撥函式生成 Request 。
    • 在回撥函式內分析返回的(網頁)內容返回 Item 物件或者 Request 或者一個包括二者的可迭代容器。 返回的Request物件之後會經過Scrapy處理,下載相應的內容,並呼叫設定的callback函式(函式可相同)。
      建立請求
    • 在回撥函式內,您可以使用 選擇器(Selectors) (您也可以使用BeautifulSoup, lxml 或者您想用的任何解析器) 來分析網頁內容,並根據分析的資料生成item。
    • 最後,由spider返回的item將被存到資料庫(由某些 Item Pipeline 處理)或使用 Feed exports 存入到檔案中。
# coding=utf-8
from scrapy.selector import Selector
from scrapy.http import Request, FormRequest, HtmlResponse
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from xiami.items import XiamiItem
from sys import argv


class XiamiSpider(CrawlSpider):
    print argv
    name = "xiaoxia"  # 爬蟲名:小蝦
    allowed_domains = ["xiami.com"]
    start_urls = [
        "http://www.xiami.com"
    ]
    account_number = '[email protected]'  # 換上你的賬號
    password = '159661312'  # 換上你的密碼
    headers = {
        "Accept": "application/json, text/javascript, */*; q=0.01",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "zh-CN,zh;q=0.8",
        "Connection": "keep-alive",
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                      "(KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
        "Referer": "https://login.xiami.com/member/login?spm=a1z1s.6843761.226669498.1.2iL1jx"
    }
    '''
    "User-Agent":
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/57.0.2987.133 Safari/537.36",
    '''
    rules = {
        Rule(LinkExtractor(allow=('/space/lib-song',)), callback='parse_page', follow=True),
    }

    # 重寫了start_request方法,Spider類不會再自動呼叫該方法來為start_url中的url建立Request
    def start_requests(self):
        return [Request("https://login.xiami.com/member/login",
                        meta={'cookiejar': 1},
                        callback=self.post_login)]

    # FormRequest
    def post_login(self, response):
        print 'Preparing login'
        # 下面這句話用於抓取請求頁面後返回頁面彙總的_xiamitoken欄位的文字,用於成功提交表單
        _xiamitoken = Selector(response).xpath('//input[@name="_xiamitoken"]/@value').extract_first()
        print '驗證資訊: ', _xiamitoken
        # FormRequest.from_response是Scrapy提供的一個函式,用於post表單
        # 登陸成功後,會呼叫after_login回撥函式
        return [FormRequest.from_response(response,
                                          meta={'cookiejar': response.meta['cookiejar']},
                                          headers=self.headers,
                                          formdata={
                                              'source': 'index_nav',
                                              '_xiamitoken': _xiamitoken,
                                              'email': self.account_number,
                                              'password': self.password
                                          },
                                          callback=self.after_login,
                                          dont_filter=True)]

    def after_login(self, response):
        print 'after login======='
        for url in self.start_urls:
            yield Request(url, meta={'cookiejar': response.meta['cookiejar']})  # 建立Request

    def _requests_to_follow(self, response):
        if not isinstance(response, HtmlResponse):
            return
        seen = set()
        for n, rule in enumerate(self._rules):
            links = [lnk for lnk in rule.link_extractor.extract_links(response)
                     if lnk not in seen]
            if links and rule.process_links:
                links = rule.process_links(links)
            for link in links:
                seen.add(link)
                r = Request(url=link.url, callback=self._response_downloaded)
                # 重寫
                r.meta.update(rule=n, link_text=link.text, cookiejar=response.meta['cookiejar'])
                yield rule.process_request(r)

    def parse_page(self, response):
        # print 'hh'
        mysong_list = Selector(response)
        songs = mysong_list.xpath('//td[@class="song_name"]/a/@title').extract()
        print songs[0]
        for song in songs:
            item = XiamiItem()
            item['title'] = 'xiami_music'
            item['name'] = self.account_number
            item['song'] = song
            yield item
        # print '---\n'
        # nexturl = mysong_list.xpath('//a[@class="p_redirect_l"]/@href').extract_first()
        # yield self.make_requests_from_url(nexturl)
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
import codecs
from scrapy.exceptions import DropItem


class XiamiPipeline(object):
    def __init__(self):
        self.song_seen = set()
        self.file = codecs.open('xiamisongs.jl', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        """
        每個item pipeline元件都需要呼叫該方法,
        這個方法必須返回一個Item(或任何整合類)物件,
        或丟擲DropItem異常,
        被丟棄的item將不被後面的pipeline處理
        :param item:
        :param spider:
        :return:
        """
        # 過濾缺失資料
        # if True:
        #   return item
        # else:
        #   raise DropItem('reason')
        if spider.name == 'xiaoxia':
            if item['song'] in self.song_seen:
                raise DropItem('Duplicate song found: %s' % item['song'])
            else:
                self.song_seen.add(item['song'])
                '''儲存到json檔案(非必須)'''
                line = json.dumps(dict(item), ensure_ascii=False) + '\n'
                self.file.write(line)
                return item

    def close_spider(self, spider):
        print 'spider close'
        self.file.close()
# -*- coding: utf-8 -*-

# Scrapy settings for xiami project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
#     http://doc.scrapy.org/en/latest/topics/settings.html
#     http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
#     http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html

BOT_NAME = 'xiami'

SPIDER_MODULES = ['xiami.spiders']
NEWSPIDER_MODULE = 'xiami.spiders'


# Crawl responsibly by identifying yourself (and your website) on the user-agent
# USER_AGENT = 'xiami (+http://www.xiami.com)'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# Configure maximum concurrent requests performed by Scrapy (default: 16)
# #CONCURRENT_REQUESTS = 32

# Configure a delay for requests for the same website (default: 0)
# See http://scrapy.readthedocs.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.25
# The download delay setting will honor only one of:
# #CONCURRENT_REQUESTS_PER_DOMAIN = 16
# #CONCURRENT_REQUESTS_PER_IP = 16

# Disable cookies (enabled by default)
COOKIES_ENABLED = True

# Disable Telnet Console (enabled by default)
# #TELNETCONSOLE_ENABLED = False

# Override the default request headers:
# #DEFAULT_REQUEST_HEADERS = {
#   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
#   'Accept-Language': 'en',
# }

# Enable or disable spider middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
# #SPIDER_MIDDLEWARES = {
#    'xiami.middlewares.MyCustomSpiderMiddleware': 543,
# }

# Enable or disable downloader middlewares
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
# #DOWNLOADER_MIDDLEWARES = {
#    'xiami.middlewares.MyCustomDownloaderMiddleware': 543,
# }

# Enable or disable extensions
# See http://scrapy.readthedocs.org/en/latest/topics/extensions.html
# # EXTENSIONS = {
#    'scrapy.extensions.telnet.TelnetConsole': None,
# }

# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'xiami.pipelines.XiamiPipeline': 300,  # 0-1000表示執行順序
}

# Enable and configure the AutoThrottle extension (disabled by default)
# See http://doc.scrapy.org/en/latest/topics/autothrottle.html
# #AUTOTHROTTLE_ENABLED = True
# The initial download delay
# #AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
# #AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
# #AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
# #AUTOTHROTTLE_DEBUG = False

# Enable and configure HTTP caching (disabled by default)
# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
# #HTTPCACHE_ENABLED = True
# #HTTPCACHE_EXPIRATION_SECS = 0
# #HTTPCACHE_DIR = 'httpcache'
# #HTTPCACHE_IGNORE_HTTP_CODES = []
# #HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
#!/usr/bin/python
# coding=utf-8
# 開始爬蟲的指令碼檔案

from scrapy.cmdline import execute
# execute('scrapy crawl xiaoxia'.split())
execute('scrapy crawl xiaoxia -o xiamisongs.jl'.split())

這是草稿,下週再修改完善

相關推薦

Python使用者蝦米音樂的歌

Python的爬蟲非常簡單,現在又有成熟的爬蟲框架scrapy。現在,我們來用scrapy爬取自己蝦米歌單上的歌曲。 通過這篇部落格,你將學到: 基本的爬蟲設計 模擬登陸 維持登陸狀態 Xpath (中的一點皮毛233)。本文預設讀者已經通過scrap

怎麽Python小視頻? 資深程序員都這樣的(附源碼)

aid option rip size with open url var mark open 簡介 抖音,是一款可以拍短視頻的音樂創意短視頻社交軟件,該軟件於2016年9月上線,是一個專註年輕人的15秒音樂短視頻社區。用戶可以通過這款軟件選擇歌曲,拍攝15秒的音樂短視頻

喜歡抖上面的音樂怎麼辦?Python音樂並分類放置資料夾

最近小編也在刷著抖音,上面的小哥哥、小姐姐各個都是人才,小編超喜歡裡面的 歌也挺好聽的,小編就打算把抖音上面歌曲都下載並且分類,把自己的喜歡的歌換成手機鈴聲,那麼抖音上面都有那些好聽的歌呢,比如: 《最美的期待》 周筆暢 《那個人》 周延英 《Panama》 Matteo 《病變

Python網易雲音樂上的Hip-hop歌,分析rapper如何押韻

line gone 謠言 大致 -i 態度 大眾 其中 當前 緣起 《中國有嘻哈》這個節目在這個夏天吸引了無數的目光,也讓嘻哈走進了大眾的視野。作為我今年看的唯一一個綜藝節目,它對我的影響也蠻大。這個夏天,我基本都在杭州度過,在上下班的taxi上,我幾乎都在刷這個節目,最後

python微博數據並生成詞雲

font 意思 extra 很多 返回 json 自己 技術分享 pre 很早之前寫過一篇怎麽利用微博數據制作詞雲圖片出來,之前的寫得不完整,而且只能使用自己的數據,現在重新整理了一下,任何的微博數據都可以制作出來,放在今天應該比較應景。 一年一度的虐汪節,是繼續蹲在角落默

pythoni春秋的課程

out clas sse dir quest index 影響 png 繼續 看課中內容是用get請求進行爬取課程,自己實踐的時候發現已經被改成post請求了,下面開始 打開課程頁面 我用的火狐,然後就是F12,點擊網絡,可能會有很多包,但不影響,點擊刪除就行,然後點擊第二

Python 微信好友,最後發現一個大秘密

代碼 我們 同學 strong 分享 簽名 ast ron tps 前言 你身處的環境是什麽樣,你就會成為什麽樣的人。現在人們日常生活基本上離不開微信,但微信不單單是一個即時通訊軟件,微信更像是虛擬的現實世界。你所處的朋友圈是怎麽樣,慢慢你的思想也會變的怎麽樣。最近在學習

分手後,小夥怒Python上萬空姐照片,贏校花選舉大賽!

代碼 美女圖片 pst caption alt .... 不出 ima bee 首先展示下Python爬取到的成果: 我做什麽都要爭第一,這次的校花投票選舉大賽也不例外,雖然我是個男的......但是我看到了前女友竟然已經有三百多票排到第三名了,我怎麽能眼睜

誰當年還沒看過幾本小說!我Python全站的的小說!

nec 打印 b數 技術分享 mon 結果 鏈接 ons ide 然後再將請求發送出去,定義變量response,用read()方法觀察,註意將符號解碼成utf-8的形式,省的亂碼: 打印一下看結果: 看到這麽

項目實戰!我Python了14年所有的福彩3D信息

下載器 rap 寫入excel url req 理論 ola text port 前兩天,在網上看到一個有意思的問題:×××靠譜麽?為什麽還有那麽多的人相信×××? 暫且不說,×××是否靠譜?×××也分人而異,江湖上騙術很多,有些甚至會誤以為×××的準確度可以很高,這些操盤

微信PK10平臺開發與python微信公眾號文章

網址 谷歌瀏覽器 pytho google http 開發 微信 安裝python rom 本文通過微信提供微信PK10平臺開發[q-21528-76294] 網址diguaym.com 的公眾號文章調用接口,實現爬取公眾號文章的功能。註意事項 1.需要安裝python s

python股票資料的一點小結

一、背景 網上對於爬取股票資料有相對完善的教程。不過大部分教程都是隻能夠爬取一段時間的股票資料,針對某一隻股票的歷史資料爬取,目前還沒有看到比較好的教程。下面對近期學的東西進行一點點小結。 二、股票資料爬取網站 網上更多推薦的是東方財富的股票資料,連結為:http://quote.eas

python美女圖片

import urllib.request import os for i in range(2000, 2400): if not os.path.exists(‘tupian/’ + str(i)): os.makedirs(‘tupian/’ + str(i)) for j in

python拉勾網招聘資訊並以CSV檔案儲存

爬取拉勾網招聘資訊 1、在網頁原始碼中搜索資訊,並沒有搜到,判斷網頁資訊使用Ajax來實現的 2、檢視網頁中所需的資料資訊,返回的是JSON資料; 3、條件為北京+資料分析師的公司一共40087家,而實際拉勾網展示的資料只有 15條/頁 * 30頁 = 450條,所以需要判斷

下午不知道吃什麼?Python美團外賣評論幫你選餐!

一、介紹 朋友暑假實踐需要美團外賣APP評論這一份資料,一開始我想,這不就抓取網頁原始碼再從中提取資料就可以了嗎,結果發現事實並非如此,情況和之前崔大講過的分析Ajax來抓取今日頭條街拍美圖類似,都是通過非同步載入的方式傳輸資料,不同的是這次的是通過JS傳輸,其他的基本思路基本一致,希望那些資料

python某個詞條的原始碼

簡單例子:在百度中輸入關鍵詞,並爬取該網頁的原始碼 #-*- coding:utf-8-*- import urllib #負責url編碼處理 import urllib2 url = "http://www.baidu.com/s" word = {"wd":"冼焯庭"}

Python手機APP

本文轉自:https://mp.weixin.qq.com/s?__biz=MzAxMjUyNDQ5OA==&mid=2653558162&idx=1&sn=73ae2ee5d2453773bceec078e39ca0ed&chksm=806e3b2fb71

python有道翻譯遇到反,3分鐘反反繞過其反

利用有道翻譯的介面,自制一個翻譯程式 檢視其翻譯介面,發現post請求需要傳很多引數,而且經過測驗,satl,sigh屬於動態生成的,遇到這種問題怎麼辦?當然有時間的情況下,可以去研究這些引數在哪個響應中返回,或者怎麼構造,但是一般在工作中我們可能需求來了,不

Python微博資料生成詞雲圖片

很早之前寫過一篇怎麼利用微博資料製作詞雲圖片出來,之前的寫得不完整,而且只能使用自己的資料,現在重新整理了一下,任何的微博資料都可以製作出來,放在今天應該比較應景。 一年一度的虐汪節,是繼續蹲在角落默默吃狗糧還是主動出擊告別單身汪加入散狗糧的行列就看你啦,七夕送什麼才有心意,程式猿可以試試用

教你python喜馬拉雅FM音訊,乾貨分享~

前前言 喜馬拉雅已經更換標籤,我重新更新了下程式碼,文章暫時未改,因為思路還是如此,需要的可以掃一下文末公眾號二維碼(本人會在上面發表爬蟲以及java的文章還有送書等資源福利哦),也可以直接搜尋公眾號“ 猿獅的單身日常”,好了廣告結束... 前言 之前寫過爬取圖片的一篇文章,這回來看看如