使用Scrapy shell调试一步一步开发爬虫

2020-06-24 17:03:42 浏览数 (1)

导读

很多文章可能直接给你一个爬虫的代码,但这些代码是怎么写出来的,可能往往语焉不详。本文不同,本文并不着重如何写一个爬虫项目,而是一步一步地教会你、一行一行地写出具体的爬虫代码

本文以爬取时光网电影的TOP100的电影信息为例,需要爬取信息的首页地址为http://www.mtime.com/top/movie/top100/

注意

本文是基于Scrapy写成的,因此在测试本文之前应先安装Scrapy包

首先输入如下命令来查看是否可正常访问该网站:

代码语言:javascript复制
scrapy shell http://www.mtime.com/top/movie/top100/

可以看到生成如下反馈:

通过上图的response,看到200说明服务器响应成功,说明该网站没有做反爬处理,该网站欢迎爬虫。

用浏览器的“检查”元素的功能,可以看到电影列表位于如下元素中:

从上面可以看出,所有电影列表都位于 id为"asyncRatingRegion"的ul元素内,每个li元素就代表一部电影。

因此可输入如下代码来“爬取”该页面内所有电影。

代码语言:javascript复制
response.xpath('//ul[@id="asyncRatingRegion"]/li').extract()

该命令将会看到如下输出:

接下来使用如下命令将所有li元素赋值给moive_list变量:

代码语言:javascript复制
movie_list =response.xpath('//ul[@id="asyncRatingRegion"]/li')

接下来movie_list中每个li元素对应一部电影。

每部电影的详细介绍链接、图片位于如下div元素内。

使用如下命令可提取第一部电影的链接:

代码语言:javascript复制
movie_list[0].xpath('div[@class="mov_pic"]/a/@href').extract_first()

执行上面命令可看到如下输出:

使用如下命令可提取第一部电影的图片:

代码语言:javascript复制
movie_list[0].xpath('div[@class="mov_pic"]/a/img/@src').extract_first()

运行上面命令看到如下输出:

每部电影的名称、导演、主演、简介位于如下div元素内。

使用如下命令可提取第一部电影的名称:

代码语言:javascript复制
movie_list[0].xpath('div[@class="mov_con"]/h2/a/text()').extract_first()

运行上面命令看到如下输出:

使用如下命令可提取第一部电影的所有导演(div下的第1个p元素):

代码语言:javascript复制
movie_list[0].xpath('div[@class="mov_con"]/p')[0].xpath('./a/text()').extract()

运行上面命令看到如下输出:

使用如下命令可提取第一部电影的所有主演(div下的第2个p元素):

代码语言:javascript复制
movie_list[0].xpath('div[@class="mov_con"]/p')[1].xpath('./a/text()').extract()

运行上面命令看到如下输出:

使用如下命令可提取第一部电影的简介(div下的第4个p元素):

代码语言:javascript复制
movie_list[0].xpath('div[@class="mov_con"]/p')[3].xpath("./text()").extract_first()

运行上面命令看到如下输出:

每部电影的评分信息位于如下div元素内。

使用如下命令可提取第一部电影的得分:

代码语言:javascript复制
movie_list[0].xpath('div[@class="mov_point"]/b/span/text()').extract()

运行上面命令看到如下输出:

该网站将电影得分的整数部分和小数部分进行了分开显示,因此我们需要将它们拼接在一起,使用如下命令即可。

代码语言:javascript复制
''.join(movie_list[0].xpath('div[@class="mov_point"]/b/span/text()').extract())

执行该命令将可看到电影的正常得分。

使用如下命令可提取第一部电影的评分人数信息:

代码语言:javascript复制
movie_list[0].xpath('div[@class="mov_point"]/p/text()').extract_first()

运行上面命令看到如下输出:

虽然上面交互式爬虫只是处理了movie_list的第一个元素,但程序只要使用循环依次处理movie_list的每个元素即可爬取页面的所有电影信息。

电影的翻页信息位于下面如下元素中

使用如下命令可提取第2页的页面链接

代码语言:javascript复制
response.xpath('//div[@id="PageNavigator"]/a')[1].xpath('./@href').extract_first()

运行上面命令可看到如下输出:

因此程序爬取完当前页面的电影信息之后,继续打开下一个页面爬取即可。

只要将上面代码复制到爬虫项目的Spider中即可开发一个完整的爬虫夏目,例如如下Spider代码。

代码语言:javascript复制
import scrapy
from MtimeSpider.items import MtimespiderItem
 
page_no = 0

class MovieSpiderSpider(scrapy.Spider):
  # 定义spider的名字
    name = 'movie_spider'
  # 爬取的域名
    allowed_domains = ['www.mtime.com']
  # 从哪个页面开始
    start_urls = ['http://www.mtime.com/top/movie/top100/']
    def parse(self, response):
        global page_no
        # 爬取所有电影元素
        movie_list = response.xpath('//ul[@id="asyncRatingRegion"]/li')
        for movie_li in movie_list:
            item = MtimespiderItem()
            # 电影介绍页面的url
            item['url'] = movie_li.xpath('div[@class="mov_pic"]/a/@href').extract_first()
            # 电影图片的url
            item['img_url'] = movie_li.xpath('div[@class="mov_pic"]/a/img/@src').extract_first()
            # 电影标题
            item['title'] = movie_li.xpath('div[@class="mov_con"]/h2/a/text()').extract_first()
            # 电影导演
            item['directors'] = movie_li.xpath('div[@class="mov_con"]/p')[0].xpath('./a/text()').extract()  
            if len(movie_li.xpath('div[@class="mov_con"]/p')) == 4:
                # 电影主演
                item['actors'] = movie_li.xpath('div[@class="mov_con"]/p')[1].xpath('./a/text()').extract()  
                # 电影简介
                item['description'] = movie_li.xpath('div[@class="mov_con"]/p')[3].xpath("./text()").extract_first()
            else:
                # 电影主演
                item['actors'] = ''
                # 电影简介
                item['description'] = movie_li.xpath('div[@class="mov_con"]/p')[2].xpath("./text()").extract_first()
            # 电影得分
            item['mark'] = ''.join(movie_list[0].xpath('div[@class="mov_point"]/b/span/text()').extract())      
            # 电影得分信息
            item['mark_info'] = movie_li.xpath('div[@class="mov_point"]/p/text()').extract_first()
            yield item

        page_no  = 1
        if page_no <= 9:    
            # 获取下一页的链接
            new_link = response.xpath('//div[@id="PageNavigator"]/a')[page_no].xpath('./@href').extract_first()
            # 再次请求下一个页面
            yield scrapy.Request(new_link, callback=self.parse)

本文结束

0 人点赞