当前位置 主页 > 服务器问题 > Linux/apache问题 >

    Python利用Scrapy框架爬取豆瓣电影示例(2)

    栏目:Linux/apache问题 时间:2020-01-29 21:21

    import scrapy
     
     
    class DoubanItem(scrapy.Item):
      ranking = scrapy.Field()  # 排名
      name = scrapy.Field()  # 电影名
      introduce = scrapy.Field() # 简介
      star = scrapy.Field()  # 星级
      comments = scrapy.Field()  # 评论数
      describe = scrapy.Field()  # 描述

    4、数据爬取

    打开之前在spiders文件夹下创建的爬虫文件movie.py如下所示,以及自动创建了三个变量和一个方法,在parse方法中进行返回数据response的处理,我们需要在start_urls提供爬虫的入口地址。注意爬虫会自动过滤掉allowed_domains之外的域名,因此需要注意这个变量的赋值

    # spiders/movie.py
    import scrapy
     
     
    class MovieSpider(scrapy.Spider):
      # 爬虫名
      name = 'movie'
      # 允许爬取的域名
      allowed_domains = ['movie.douban.com']
      # 入口url
      start_urls = ['https://movie.douban.com/top250']
     
      def parse(self, response):
        pass

    在进行数据爬取之前首先要设置一些网络代理,在settings.py文件内找到USER_AGENT变量修改如下:

    USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0'
    

    可以在命令行通过如下命令启动名为douban的爬虫:scrapy crawl douban,也可以编写一个启动文件run.py文件如下,运行即可

    from scrapy import cmdline
    cmdline.execute('scrapy crawl movie'.split())

    接下来要对爬取到的数据进行过滤,通过Xpath规则可以使我们便捷地选中网页中的指定元素,如下图所示,每个电影条目都包裹在<ol class="grid_view">下的一个<li>标签,因此通过xpath://ol[@class='grid_view']/li 就选中了本页面所有的电影条目。可以通过谷歌浏览器的Xpath插件或者火狐浏览器的ChroPath获得xpath值,在浏览器右键查看元素,弹出如下图所示的开发者工具,其中最右边就是ChroPath插件,它直观地显示了元素的Xpath值: //div[@id='wrapper']//li
     

    爬虫response对象的xpath()方法可以直接处理xpath规则字符串并返回对应的页面内容,这些内容都是选择器对象Selector,可以进一步作细化的内容选取,通过xpath选择出其中的电影名字、简介、评价、星级等内容,即之前在items.py文件中所定义的数据结构DoubanItem。循环遍历每个电影列表从其中爬取到准确的电影信息,并保存为DoubanItem对象item,最后通过yield将item对象从Spiders返回到Item管道。

    爬虫除了从页面提取Item数据之外还会爬取url链接从而形成下一页的Request请求,如下图所示为豆瓣页面底部的下一页信息,第二页的参数为"?start=25&filter=",与网站地址https://movie.douban.com/top250拼接起来就可以得到下一页面的地址。和上面一样通过xpath提取该内容,如果不为空,则拼接得到的Request请求yield提交给调度器

    最终的爬虫movie.py文件如下

    # -*- coding: utf-8 -*-
    import scrapy
    from items import DoubanItem
     
     
    class MovieSpider(scrapy.Spider):
      # 爬虫名
      name = 'movie'
      # 爬取网站的域名
      allowed_domains = ['movie.douban.com']
      # 入口url
      start_urls = ['https://movie.douban.com/top250']
     
      def parse(self, response):
        # 首先抓取电影列表
        movie_list = response.xpath("//ol[@class='grid_view']/li")
        for selector in movie_list:
          # 遍历每个电影列表,从其中精准抓取所需要的信息并保存为item对象
          item = DoubanItem()
          item['ranking'] = selector.xpath(".//div[@class='pic']/em/text()").extract_first()
          item['name'] = selector.xpath(".//span[@class='title']/text()").extract_first()
          text = selector.xpath(".//div[@class='bd']/p[1]/text()").extract()
          intro = ""
          for s in text: # 将简介放到一个字符串
            intro += "".join(s.split()) # 去掉空格
          item['introduce'] = intro
          item['star'] = selector.css('.rating_num::text').extract_first()
          item['comments'] = selector.xpath(".//div[@class='star']/span[4]/text()").extract_first()
          item['describe'] = selector.xpath(".//span[@class='inq']/text()").extract_first()
          # print(item)
          yield item # 将结果item对象返回给Item管道
        # 爬取网页中的下一个页面url信息
        next_link = response.xpath("//span[@class='next']/a[1]/@href").extract_first()
        if next_link:
          next_link = "https://movie.douban.com/top250" + next_link
          print(next_link)
          # 将Request请求提交给调度器
          yield scrapy.Request(next_link, callback=self.parse)