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

前言

利用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级地震,希望同胞安好

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容