基于Scrapy 爬取豆瓣TOP电影(经典到不能再经典的例子了,23333)

先附上源代码的github 链接:传送门

 

手写了那么多次爬虫,多多少少都会发现,很多代码都在重用,有代码经常性的在重复使用,说明,这些代码肯定有框架可以直接实现,Scrapy就是写爬虫最常用的一个框架,本着学习与娱乐结合的意愿,咱就用这个框架去爬一下最经典的豆瓣top250的电影吧。

 

当然,本文是参照了博客:传送门 来写的,这是一个经典的爬虫案例,所以,大致代码,大家都差不多。

好了,废话不多说。直接开干。

 

首先我们先看看:

红线标记的地方,就是本次我们需要爬取的内容:

包括:电影标题,电影信息,电影评分,电影金句(哈哈,就当这么说吧~)

 

对框架有啥不理解的,详细可以看这个:传送门

以本文为例,首先得先安装scrapy ,直接命令行:

pip3 install scrapy

安装好之后,先创建一个Scrapy项目,进入您打算存储代码的目录中,运行下列命令:

scrapy startproject Douban

你就会发现目录下是这个样子的:

当然,其中的mydouban.py , movie.xlsx, 以及main.py,你刚创建的时候是没有的,这是我的项目创建的,先忽略,后面会说。

那么这些文件分别是:

  • scrapy.cfg: 项目的配置文件
  • Douban/: 该项目的 python 模块。之后您将在此加入代码。
  • Douban/items.py: 项目中的 item 文件。
  • Douban/pipelines.py: 项目中的 pipelines 文件。
  • Douban/settings.py: 项目的设置文件。
  • Douban/spiders/: 放置 spider 代码的目录。

好了,这个时候,整个项目架构是有了,那么我们先开始第一步:定义Item

最上面,已经说了本文爬虫需要爬的东西是啥,那么我们为此定义一下对应的Item

当你按照上述流程创建好项目之后,打开items.py,你能看到一个DoubanItem的类,当然,最开始里面啥也没有,

我们需要“电影标题,电影信息,电影评分,电影金句”,那么分别为这四个内容根据scrapy的规定,创建变量用来保存资源。

title = scrapy.Field()
movie_info = scrapy.Field()
score = scrapy.Field()
quote = scrapy.Field()

Item 创建好了,这回得开始创建爬虫了,在spider的目录下创建我们的第一个爬虫:mydouban.py

Spider 是用户编写用于从单个网站(或者一些网站)爬取数据的类。

其包含了一个用于下载的初始 URL,如何跟进网页中的链接以及如何分析页面中的内容, 提取生成 item 的方法。

为了创建一个 Spider,您必须继承 scrapy.Spider 类, 且定义以下三个属性:

  • name: 用于区别 Spider。 该名字必须是唯一的,您不可以为不同的 Spider 设定相同的名字。
  • start_urls: 包含了 Spider 在启动时进行爬取的 url 列表。 因此,第一个被获取到的页面将是其中之一。 后续的 URL 则从初始的 URL 获取到的数据中提取。
  • parse() 是 spider 的一个方法。 被调用时,每个初始 URL 完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成 item)以及生成需要进一步处理的 URL 的 `Request 对象。
# -*- coding:utf-8 -*-
"""

Created on 2019/6/22
@author:Ray Li

"""

import scrapy
from Douban import items


class MyDouban(scrapy.Spider):
    name = "Douban"
    start_urls = ["https://movie.douban.com/top250"]

    url = "https://movie.douban.com/top250"

    def parse(self, response):
        item = items.DoubanItem()
        movies = response.xpath('//div[@class="info"]')

        for movie in movies:
            title = movie.xpath('div[@class="hd"]/a/span[@class="title"]/text()').extract()
            # print(title)
            full_title = ''
            for each in title:
                full_title += each

            movie_info = movie.xpath('div[@class="bd"]/p/text()').extract()[0]

            score = movie.xpath('div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()').extract()[0]

            quote = movie.xpath('div[@class="bd"]/p[@class="quote"]/span/text()').extract()[0]

            # print("######################################")
            # print(movie_info)
            # print(score)
            # print(quote)
            # print(title)
            # print("######################################")

            item['title'] = full_title
            item['movie_info'] = movie_info
            item['quote'] = quote
            item['score'] = score

            yield item

        nextPage = response.xpath('//span[@class="next"]/a/@href').extract()

        if nextPage:
            nextPage = nextPage[0]
            yield scrapy.Request(self.url + nextPage, callback=self.parse)

看到这么一大串,先别怕,根据描述一步步来:

首先我们创建了一个spider类 :MyDouban,继承了scrapy.Spider

根据上文提到的三个属性,name,URL,parse

那么最开始,我们得定义一个爬虫的名字,和爬虫要爬取的初始URL集合吧~

然后就要创建一个parse函数不~

这样大致的框架已经出来,具体,我们得关注parse 内的函数该怎么写。

我们先看一下要爬取的网页结构:

是不是发现,我们要爬取的内容在一个class属性为“info”的div中?,所以啊,第一个代码:

movies = response.xpath('//div[@class="info"]')

利用xpath  去获取网页中所有的,class属性为“info”的div,那么关于xpath 不会的话 ,请参照W3C文档:传送门

那么后续的获取“title”,“score”什么的就都差不多了。

东西拿到手之后,我们得存在之前我们创建的Item里啊,所以:

item['title'] = full_title
item['movie_info'] = movie_info
item['quote'] = quote
item['score'] = score
yield item

最后把item对象返回。

好了这个时候,其实我们的爬虫就快完成了,第一页的内容我们就都爬取出来了,

如果你就爬一页,那么这个爬虫到“yield item” 就已经结束了,

但是250个电影肯定一页放不下啊,所以我们在爬完一页之后(for循环结束后),得获取到下一次爬取的链接,

也就是下一页的链接。

nextPage = response.xpath('//span[@class="next"]/a/@href').extract()

    if nextPage:
        nextPage = nextPage[0]
        yield scrapy.Request(self.url + nextPage, callback=self.parse)

利用回调操作,下一次,他又会将新的URL 调回parse去爬取(当然,固定格式就是这样)。

 

oK ,我们这回终于完成了爬虫,但是,还忽略了一个问题,你好歹也伪装一下爬虫吧,还有你也没把数据给存下来啊。

伪装好办,不是有个setting.py文件嘛,打开之后,去看里面的注释,把USER_AGENT的注释给去掉,改成你的浏览器USER_AGENT,这样就能假装我们是通过浏览器访问的啦。

USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'

为了保存数据,我们就要编辑pipelines.py了,他里面可以将传进来的Item做自定义的一些操作。

当 Item 在 Spider 中被收集之后,它将会被传递到 Item Pipeline,一些组件会按照一定的顺序执行对 Item 的处理。

每个 item pipeline 组件(有时称之为“Item Pipeline”)是实现了简单方法的 Python 类。他们接收到 Item 并通过它执行一些行为,同时也决定此 Item 是否继续通过 pipeline,或是被丢弃而不再进行处理。

以下是 item pipeline 的一些典型应用:

  • 清理 HTML 数据
  • 验证爬取的数据(检查 item 包含某些字段)
  • 查重(并丢弃)
  • 将爬取结果保存到数据库中

编写你自己的 item pipeline 很简单,每个 item pipeline 组件是一个独立的 Python 类,同时必须实现以下方法:

process_item(self, item, spider)

每个 item pipeline 组件都需要调用该方法,这个方法必须返回一个 Item (或任何继承类)对象, 或是抛出 DropItem 异常,被丢弃的 item 将不会被之后的 pipeline 组件所处理。

那么好办,数据都已经保存在Item里了,那么我们,就把Item里的数据写到EXCEL 文件中去把:

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

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import openpyxl


class DoubanPipeline(object):
    def __init__(self):
        self.wb = openpyxl.Workbook()
        self.sheet = self.wb.create_sheet('电影TOP250')
        self.sheet.append(['电影标题', '电影信息', '电影评分', '电影金句'])

    def process_item(self, item, spider):
        print(type(item['score']))
        line = [item['title'], item['movie_info'].strip(), item['score'], item['quote']]
        self.sheet.append(line)
        self.wb.save("movie.xlsx")
        return item

按照流程创建好的项目里,打开pipelines.py,可以看到DoubanPipeline 这个类,里面有一个没有函数体的process_item函数,然后自己在里面对Item 内容进行处理就好了,对了,编辑好pipelines.py后,为了启用一个 Item Pipeline 组件,你必须将它的类添加到 ITEM_PIPELINES 配置

ITEM_PIPELINES = {
   'Douban.pipelines.DoubanPipeline': 300,
}

后面的300 是优先级哈,分配给每个类的整型值,确定了他们运行的顺序,item 按数字从低到高的顺序,通过 pipeline,通常将这些数字定义在 0-1000 范围内。

 

最后呢,你可以通过命令行的方式去执行:

scrapy crawl Douban

这样就能启动爬虫,然后等爬虫结束就能拿到自己的资源了。

当然,先麻烦的话,可以自己创建一个main.py:

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

Created on 2019/6/22
@author:Ray Li

"""

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

这样就可以在pycharm里面直接运行了!

那么,本文到这就结束啦,哈哈,很简单把~!

最后附上,爬虫获取的电影资源截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值