美文网首页
【scrapy】爬取豆瓣top250的电影信息

【scrapy】爬取豆瓣top250的电影信息

作者: Julianlee107 | 来源:发表于2017-08-08 23:22 被阅读0次

前言

利用scrapy爬取豆瓣上top250条电影信息其实挺容易的,主要是用来熟悉一下如何利用scrapy快速写一个爬虫。

开始启动一个scrapy项目

进入到想要创建scrapy项目的目录下

scrapy startproject douban_top_250

当我们想要写一个爬虫的时候后要知道我们想要从哪爬取,想要爬取什么,爬取下来的数据我们需要进行什么样的处理。

设计需要爬取的item

先打开豆瓣电影top250这个页面。


可以看到这个页面展示了电影的名字、排名、导演、演员等信息。当我们点击每一个链接时还会有更多的信息:

例如《肖申克的救赎》,这个详情页面展示了评分评论数还有用户给出的评论等信息。
所以,我们可以爬取下这部电影的名称、导演、编剧、主演、类型、制片国家、语言、上映时间、片长、别名、排名、评分,评论人数等信息。

import scrapy
#items.py
#这个文件
class Douban_Top_250Item(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    chinese_name = scrapy.Field()
    english_name = scrapy.Field()
    director = scrapy.Field()
    screenwriter = scrapy.Field()
    main_actors = scrapy.Field()
    type = scrapy.Field()
    district = scrapy.Field()
    show_date = scrapy.Field()
    duration = scrapy.Field()
    other_name = scrapy.Field()
    score = scrapy.Field()
    rank = scrapy.Field()
    language = scrapy.Field()
    count_conmment = scrapy.Field()

开始着手Spider

from scrapy import Spider
from scrapy.http import Request
class crawlDoubanMovie(Spider):
    name = "douban_top_250"
    #因为豆瓣屏蔽了scrapy默认的header。
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36',
    }
    def start_requests(self):
        url = 'https://movie.douban.com/top250'
        yield Request(url, headers=self.headers)
    def parse(self,response):
         #后面单独来写。
        pass
      
    }

这样实现了一个能访问豆瓣电影top250的超简单爬虫。
parse函数是scrapy中用来对url进行处理的默认函数,也可以在Request中加入新的callback函数。

#在crawlDoubanMovie前面有4个indent。暂时省略了
    def parse(self, response):
        #将每部电影的URL传入到一个专门的函数中进行数据提取,也可以直接在parse函数中进行处理
        post_urls = response.xpath('//ol[@class="grid_view"]/li//div[@class="hd"]/a/@href').extract()
        for post_url in post_urls:
            yield Request(url =parse.urljoin(response.url,post_url),callback=self.parse_detail,headers=self.headers)
      

使用了XPath对节点进行了选择


在对页面中每一个电影的链接进行请求后,这个页面的有用信息基本上就爬取完成,还剩下一个很重要的操作,就是对下一页的链接进行请求然后进行爬取。通过查看页面,发现可以对“后页”这个链接进行请求


最后一页时后页无链接

也可以对下面的“1,2,3,4....”链接进行获取,不过这样只能针对页数很少的网站。

def parse(self,response):
     ...
    next_url = response.xpath('//*[@id="content"]/div/div[1]/div[2]/span[3]/a/@href').extract_first()
        yield Request(parse.urljoin(response.url,next_url),headers=self.headers)

自定义一个parse_detail函数,对电影详情页面的数据进行处理。

#我使用了ItemLoader,也可以不使用loader直接将值通过键值对的形式传给Item.py
from scrapy.loader import ItemLoader
    def parse_detail(self,response):
        text_xpath="//*[@id='info']/text()"
        text = [element.strip() for element in response.xpath(text_xpath).extract()]
        while "" in text:
            text.remove("")
        while "/" in text:
            text.remove("/")
        print(text)
        movieItemLoader = ItemLoader(item=Douban_Top_250Item(),response=response)
        movieItemLoader.add_xpath("chinese_name","//*[@id='content']/h1/span[1]/text()")
        movieItemLoader.add_xpath("english_name","//h1/span[1]/text()")
        movieItemLoader.add_xpath("director","//*[@id='info']/span[1]/span[@class='attrs']/a/text()")
        movieItemLoader.add_xpath("screenwriter","//*[@id='info']/span[2]/span[@class='attrs']/a/text()")
        movieItemLoader.add_xpath("main_actors",'//*[@id="info"]/span[3]/span[@class="attrs"]/a/text()')
        movieItemLoader.add_xpath("type",'//*[@id="info"]/span[@property="v:genre"]/text()')
        movieItemLoader.add_value("district",text[0])
        movieItemLoader.add_value("language",text[1])
        movieItemLoader.add_value("other_name",text[2])
        movieItemLoader.add_xpath("show_date",'//*[@id="info"]/span[@property="v:initialReleaseDate"]/text()')
        movieItemLoader.add_xpath("duration",'*[@id="info"]/span[@property="v:runtime"]/text()')
        movieItemLoader.add_xpath("rank",'//*[@id="content"]/div[1]/span[1]/text()')
        movieItemLoader.add_xpath("count_comment","//span[@property=v:votes]/text()")
        movieItemLoader.add_xpath("score",'//span[@property="v:average"]/text()')
        movieItem = movieItemLoader.load_item()
        yield movieItem

上面代码中的text是为了处理

纯文本

这样的纯文本,它存在于父节点的文本中,所以要进行处理才能提取到。(个人感觉是豆瓣很懒。。。写的很难看)

关于ItemLoader

ItemLoader中将所有爬取到的信息都设置为list,所以要设置好ItemLoader的output_processors。通过查看ItemLoader的源码


可以看到,我们可以改变default_output_processor
那么我们在item中进行写一个自己的ItemLoader

#items.py
from scrapy.loader.processors import TakeFirst
class MovieItemLoader(ItemLoader):
    default_output_processor = TakeFirst

这样就可以将返回的item中取出list中的第一个元素。可是有的数据本身就是一个list,我们可以通过一个方法,将默认的输出给覆盖掉。

def return_value(value):
    return value

value即是itemloader所传入的值
既然要使用自己写的ItemLoader,就需要在spider中修改使用的默认ItemLoader

from ..items import MovieItemLoader
    ...
     movieItemLoader = MovieItemLoader(item=Douban_Top_250Item(),response=response
    ...
)

剩下的即是在items中写一些方法将itemloader传入的value进行input_processor和output_processor的处理。使用的大概方法即是在scrapy.Filed()中添加方法,可以使用MapCompose将多个方法组合在
一起。
例如:

screenwriter = scrapy.Field(
                input_processor=方法,
                output_processor=方法
)

最后

最后肯定要将采集好的数据进行存储。可以使用两种方式:一种是使用scrapy自带的feed export,另一种是自己写pipeline将数据保存为自己想要的格式,例如存入到数据库,保存为CSV,保存为json等。
以后接着写,to be continued

最后的最后

今天晚上九寨沟发生了7级地震,希望同胞安好

相关文章

网友评论

      本文标题:【scrapy】爬取豆瓣top250的电影信息

      本文链接:https://www.haomeiwen.com/subject/dryxrxtx.html