用scrapy对豆瓣top250页面爬取(多页面爬取)

2015-10-02 18:57:36

本博客采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本博客文章必须也遵循署名-非商业用途-保持一致的创作共用协议

上一篇我们讲到了,单个页面怎么使用scrapy爬取数据,现在我们来看看怎么样组织大规模的scrapy爬虫,对多个页面进行爬取,因为一般来说,爬虫是需要不止爬取一个页面,而是用来对大规模的网页进行机械化的爬取我们所需要的信息,而scrapy在这方面有些奇怪(也许是笔者功力未到,未能领会),scrapy把一个页面的的链接全部抓取到,然后保存下来一个一个爬取,爬取到新页面时,会从原有的url集合里面查找是否重复,如此一来,scrapy便可以很轻易的写一个来爬取一个大网站

实战,爬取豆瓣top250电影榜


首先在 terminal 里面输入这个来创建一个 scrapy项目:

scrapy startproject douban_spider

同样,这样我们便得到了诸如 items.pypipelines.pysettings.pyspider文件夹这些有用的文件

首先,我们编写 items.py:

import scrapy


class DoubanSpiderItem(scrapy.Item):

    movie_name=scrapy.Field()

    star=scrapy.Field()
    quote=scrapy.Field()

这回我们保存电影名,评分,和豆瓣对它的精辟的点评

因为代码和上次的很像,我就不做过多的言语了,不解的请看 用scrapy爬取豆瓣电影新片榜

接着,我们在 spider文件夹里面创建一个 douban_many_movie_spider.py的文件,来编写,我们的爬虫

在我们爬取之前,我们先看看我们要爬取的源码,来定一定xpath路径:

scrapypic

以下是爬虫程序douban_many_movie_spider.py:

from scrapy.spiders import Spider
from scrapy.http import Request
from scrapy.selector import Selector
from scrapy.spiders import Rule,CrawlSpider
from scrapy.linkextractors import LinkExtractor

from douban_spider.items import DoubanSpiderItem

class DoubanSpider(CrawlSpider):

    name="douban_many_movie_spider"

    download_delay=1

    allowed_domains=[]

    start_urls=[
        'http://movie.douban.com/top250?start=0&filter=&type='
    ]

    rules=(
        Rule(LinkExtractor(allow=(r'http://movie\.douban\.com/top250\?start=\d+&filter=&type=')),callback='parse_item',follow=True),
    )


    def parse_item(self,response):

        print response

        sel=Selector(response)
        item=DoubanSpiderItem()

        movie_name=sel.xpath('//span[@class="title"][1]/text()').extract()
        star=sel.xpath('//div[@class="star"]/span/em/text()').extract()
        quote=sel.xpath('//p[@class="quote"]/span[@class="inq"]/text()').extract()


        item['movie_name']=[n.encode('utf-8')  for n in movie_name]
        item['star']=[n.encode('utf-8')  for n in star]
        item['quote']=[n.encode('utf-8')  for n in quote]


        yield item

这里我来做以下解释,因为之前也说,scrapy本是用来爬取单页面的爬虫框架,所以若我以下说明有误,请在评论框提醒我

  • 首先这次不一样的,我们要引入scrapy的另一个爬虫类种 crawlspider事实上scrapy永远不止我们在上一篇用到的 spider这一种爬虫可以给用户来进行继承,而 crawlspider就是拿来帮助大规模爬取的

  • 同样的,设置你的name,start_urls等,注意!!!这里若是要设置 allowed_domains要注意写好,不然会阻止自己的爬虫爬取别的网站,而这项本就是选择项,所以我决定不写

  • rules用来规定拿到的链接的选择方式,这里可以看到我的这个正则表达式 http://movie\.douban\.com/top250\?start=\d+&filter=&type=是根据豆瓣的这几个网站的网址定的,网址在页面的下一页,下一页都有,当拿到这些链接之后,scrapy就会自动对这些链接访问,也就是我们需要的多页面爬取。然后这个rules后面要接上一个 callback,表达,当我们访问符合我们的正则表达式的链接时回调什么方法,来对我们的链接访问进行数据处理

  • 一下就是我们的回调方法 parse-item,基本和我们上一个程序没太大变化

我们的爬虫写好了,同样的,这次我也希望,能把这些数据保存成json格式,所以我们又来写我们的 pipelines.py程序:

# -*- coding: utf-8 -*-


import json
import codecs
import sys

reload(sys)
sys.setdefaultencoding('utf8')



class DoubanSpiderPipeline(object):
    def  __init__(self):
        self.file=codecs.open('douban_movie2.json',mode='wb',encoding='utf-8')
    def process_item(self, item, spider):

       line='the list:'+'\n'
       for i in range(len(item['quote'])):

            movie_name={"movie_name":item['movie_name'][i]}
            star={"start":item['star'][i]}
            quote={"quote":item['quote'][i]}
            line=line+json.dumps(movie_name,ensure_ascii=False)
            line=line+json.dumps(star,ensure_ascii=False)
            line=line+json.dumps(quote,ensure_ascii=False)+"\n"

        self.file.write(line)

    def close_spider(self,spider):
        self.file.close()
  • 因为和上一个程序,没什么不同,所以我就不多说了

也需要在 settings.py里面设置一下:

ITEM_PIPELINES={
    'douban_spider.pipelines.DoubanSpiderPipeline':300
}

接着我们就可以跑这个scrapy项目了:

scrapy crawl douban_many_movie_spider

我们便会得到一个 douban_movie2.json文件在我们同文件夹内,内容是这样的:

scrapypic

今天我的所以代码,已经这个有250个电影排名的json文件都在这里,欢迎同学们来知道围奸:

https://github.com/salamer/doubanmoviespider

python爬虫 返回首页

Designed and built with all the love in the world by the Mr.ALJUN.

@SERVER BY NGINX AND POWER BY DIGITALOCEAN.

© COPYRIGHT BY GAGASALAMER 2015