天天看點

Scrapy爬蟲(五):有限爬取深度執行個體

Scrapy爬蟲(五):有限爬取深度執行個體

  • Scrapy爬蟲五有限爬取深度執行個體
    • 豆瓣樂評分析
    • 爬蟲爬取政策
    • 建立項目
    • 運作爬蟲
該章節将實作爬取豆瓣某個音樂下所有樂評的scrapy爬蟲。

豆瓣音樂是國内音樂資料及評論網站,現在我們有個需求就是爬取豆瓣音樂下所有的音樂評論(樂評),但是樂評屬于音樂介紹下的子菜單,那麼如何來爬取這些樂評呢?咱們先不急,先看看豆瓣樂評的結構。

以周傑倫的葉惠美為例https://music.douban.com/subject/1406522/

Scrapy爬蟲(五):有限爬取深度執行個體

這個是頁面上面的部分,滑鼠往下滾動可以看到樂評

Scrapy爬蟲(五):有限爬取深度執行個體

可以看到葉惠美下有111條長評論,那麼,我們現在如何在隻知道葉惠美這首歌url的情況下,爬取下面所有的樂評呢,下面我會回答這個問題。

我了解到有這麼幾種政策,具體的可以參看wawlian的部落格

1.深度優先周遊政策

2.橫向優先搜尋政策

3.反向連結數政策

4.Partial PageRank政策

5.OPIC政策政策

6.大站優先政策

本處爬取樂評可以采用深度優先周遊的政策,因為按我們正規表達式捕獲同規則下的url,音樂頁面還有其他音樂的連結,那麼爬蟲就會跑偏,爬取樂評的時候可能會先去爬取其他音樂的樂評。如果為爬蟲設定深度,爬蟲将不會爬取更深的url,當爬完樂評後會傳回到下一個音樂url,繼續爬取。

scrapy中,我們在settings.py設定深度使用DEPTH_LIMIT,例如:DEPTH_LIMIT = 5,該深度是相對于初始請求url的深度。

經分析,可以得出豆瓣音樂樂評相對于起始音樂url的深度為4,那麼我們在settings.py設定DEPTH_LIMIT = 4

使用指令

scrapy startproject douban

MACBOOK:~ yancey$ scrapy startproject douban
New Scrapy project 'douban', using template directory '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/scrapy/templates/project', created in:
    /Users/yancey/douban

You can start your first spider with:
    cd douban
    scrapy genspider example example.com           

使用pycharm打開douban項目

Scrapy爬蟲(五):有限爬取深度執行個體

在settings.py中設定DEPTH_LIMIT = 4

BOT_NAME = 'douban'
SPIDER_MODULES = ['douban.spiders']
NEWSPIDER_MODULE = 'douban.spiders'
DEPTH_LIMIT = 4
DOWNLOAD_DELAY = 2
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36'
ROBOTSTXT_OBEY = True           

豆瓣有反爬蟲機制,是以設定延時DOWNLOAD_DELAY,及使用者代理USER_AGENT也是必要的,在google浏覽器輸入

chrome://version/

可以得到使用者代理USER_AGENT。

  • 修改items.py
from scrapy import Item, Field

# 音樂
class MusicItem(Item):
    music_name = Field()
    music_alias = Field()
    music_singer = Field()
    music_time = Field()
    music_rating = Field()
    music_votes = Field()
    music_tags = Field()
    music_url = Field()
# 樂評
class MusicReviewItem(Item):
    review_title = Field()
    review_content = Field()
    review_author = Field()
    review_music = Field()
    review_time = Field()
    review_url = Field()           
  • 新寫一個爬蟲
# coding:utf-8

from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from douban.items import MusicItem, MusicReviewItem
from scrapy import log

import re


class ReviewSpider(CrawlSpider):
    name = 'review'
    allowed_domains = ['music.douban.com']
    start_urls = ['https://music.douban.com/subject/1406522/']
    rules = (
        Rule(LinkExtractor(allow=r"/subject/\d+/reviews$")),
        Rule(LinkExtractor(allow=r"/subject/\d+/reviews\?sort=time$")),
        Rule(LinkExtractor(allow=r"/subject/\d+/reviews\?sort=time\&start=\d+$")),
        Rule(LinkExtractor(allow=r"/review/\d+/$"), callback="parse_review", follow=True),
    )

    def parse_review(self, response):
        try:
            item = MusicReviewItem()
            item['review_title'] = "".join(response.xpath('//*[@property="v:summary"]/text()').extract())
            content = "".join(
                response.xpath('//*[@id="link-report"]/div[@property="v:description"]/text()').extract())
            item['review_content'] = content.lstrip().rstrip().replace("\n", " ")
            item['review_author'] = "".join(response.xpath('//*[@property = "v:reviewer"]/text()').extract())
            item['review_music'] = "".join(response.xpath('//*[@class="main-hd"]/a[2]/text()').extract())
            item['review_time'] = "".join(response.xpath('//*[@class="main-hd"]/p/text()').extract())
            item['review_url'] = response.url
            yield item
        except Exception as error:
            log(error)           
  • 建立run.py
# coding:utf-8
from scrapy import cmdline
cmdline.execute("scrapy crawl review -o review.json".split())           

scrapy crawl review -o review.json 指令意思是,運作review爬蟲并且将結果輸出到revie.json檔案中

... ...

2016-12-27 11:15:52 [scrapy] DEBUG: Scraped from <200 https://music.douban.com/review/7948957/>
{'review_author': '真實的螃蟹',
 'review_content': '作為90後,第一次聽Jay的歌就是從這一張專輯開始,那時候都是聽盜版錄音帶。',
 'review_music': '葉惠美',
 'review_time': '',
 'review_title': '從葉惠美開始',
 'review_url': 'https://music.douban.com/review/7948957/'}
2016-12-27 11:15:52 [scrapy] DEBUG: Scraped from <200 https://music.douban.com/review/7844264/>
{'review_author': 'Flowertree',
 'review_content': '從上周清明放假開始,上海的雨就一直恹恹地下個不停,像在情局裡走不出的嬌弱女生。',
 'review_music': '葉惠美',
 'review_time': '',
 'review_title': '是雨天。',
 'review_url': 'https://music.douban.com/review/7844264/'}
2016-12-27 11:15:52 [scrapy] INFO: Closing spider (finished)
2016-12-27 11:15:52 [scrapy] INFO: Stored json feed (111 items) in: review.json
2016-12-27 11:15:52 [scrapy] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 55633,
 'downloader/request_count': 126,
 'downloader/request_method_count/GET': 126,
 'downloader/response_bytes': 1111810,
 'downloader/response_count': 126,
 'downloader/response_status_count/200': 123,
 'downloader/response_status_count/301': 3,
 'dupefilter/filtered': 220,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2016, 12, 27, 3, 15, 52, 612227),
 'item_scraped_count': 111,
 'log_count/DEBUG': 544,
 'log_count/INFO': 8,
 'request_depth_max': 4,
 'response_received_count': 123,
 'scheduler/dequeued': 123,
 'scheduler/dequeued/memory': 123,
 'scheduler/enqueued': 123,
 'scheduler/enqueued/memory': 123,
 'start_time': datetime.datetime(2016, 12, 27, 3, 15, 44, 243222)}
2016-12-27 11:15:52 [scrapy] INFO: Spider closed (finished)

Process finished with exit code 0           
  • 專題概要
  • 爬蟲簡介
  • scrapy架構及原理
  • imdb.cn爬蟲執行個體
  • 有限爬取深度執行個體
  • 多個爬蟲組合執行個體
  • 爬蟲資料存儲執行個體
  • 中間件的使用執行個體
  • scrapy的調試技巧
  • 爬蟲總結以及擴充

學習時的痛苦是暫時的 未學到的痛苦是終生的