当前位置:   article > 正文

【爬虫】Scrapy初次尝试 入门详细教程(爬取豆瓣top250电影信息)_scrapy爬虫框架爬取电影数据

scrapy爬虫框架爬取电影数据

功能
爬取豆瓣电影Top 250的电影信息(序号、电影名、介绍、星级、评论数、描述)。

运行环境
Windows10 + Anaconda + Pycharm

参考
https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html#id4
https://www.imooc.com/video/17516


一、创建项目

1.1 搭建环境

1 使用Anaconda配置好虚拟环境,包括依赖的安装。

Python3.6
scrapy
requests
urllib3
lxml 
libxml2
cssselect
parsel
w3lib
Twisted
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

安装方式:
Anaconda Prompt 常用命令

1 打开Anaconda Prompt
2 创建虚拟环境:conda create -n 环境名称 python=3.6
3 激活虚拟环境:conda activate 环境名称
4 安装库:pip install 名称 -i https://pypi.tuna.tsinghua.edu.cn/simple(使用镜像,下载更快)

安装scrapy时,会自动安装前置库。

2 打开PyCharm建立项目,并将刚刚建立的虚拟环境作为该项目编译器。
在这里插入图片描述

1.2 创建项目文件

打开PyCharm的Terminal界面,输入scrapy startproject 项目名,建立scrapy项目。

如: scrapy startproject douban
在这里插入图片描述

成功后获得如下项目目录:
在这里插入图片描述

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

1.3 创建爬虫文件

打开terminal界面,输入:

cd douban
scrapy genspider douban_spider movie.douban.com
  • 1
  • 2

在这里插入图片描述

创建名为douban_spider.py的文件爬取movie.douban.com网站。
在这里插入图片描述

1.4 定义Item

Item 是保存爬取到的数据的容器;其使用方法和python字典类似, 并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。

首先根据需要从unsplash.com获取到的数据对item进行建模。 我们需要从unsplash中获取名字,url,以及网站的描述。 对此,在item中定义相应的字段。

import scrapy


class ImgCrawlerItem(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field()
    pass
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

1.5 编写Spider

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

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

import scrapy


class ImgSpider(scrapy.Spider):
    name = 'ImgSpider'  # 用于区别Spider,该名字必须是唯一的,不可以为不同的Spider设定相同的名字。
    allowed_domains = ['unsplash.com']
    start_urls = ['https://unsplash.com/']  # 包含了Spider在启动时进行爬取的url列表。

    def parse(self, response):  # spider的一个方法
        """
        每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。
        该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。
        """
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

spider暂时不包含任何内容。

1.6 运行函数main

在Terminal内运行十分麻烦,所以创建一个main函数用于启动程序。
在这里插入图片描述

代码如下:

from scrapy import cmdline
cmdline.execute('scrapy crawl ImgSpider'.split())
  • 1
  • 2

二、编辑项目

2.1 items.py 编写

想要获取网页中的以下内容:序号、电影名、介绍、星级、评论数、描述。
在这里插入图片描述
编写items.py

import scrapy


class DoubanItem(scrapy.Item):
    serial_number = scrapy.Field()  # 序号
    movie_name = scrapy.Field()  # 电影名
    introduction = scrapy.Field()  # 介绍
    rating_num = scrapy.Field()  # 星级
    comment_num = scrapy.Field()  # 评论数
    quote = scrapy.Field()  # 描述
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.2 xpath定位

关于Xpath:https://www.jianshu.com/p/85a3004b5c06

首先为谷歌浏览器安装扩展程序:XPath
在这里插入图片描述
后面将使用XPath扩展程序定位要寻找的内容。
在这里插入图片描述
右键点击电影名——检查,即可定位到电影的位置。

该位置为<div class="article">\<ol class="grid_view">\<li>(共有25个,因为一页含有25个电影信息)

通过XPath进行定位,输入//div[@class="article"]//ol[@class="grid_view"]/li,可以看到,共找到25个结果,说明XPath输入的内容正确。
在这里插入图片描述
接下来通过XPath分别定位(XPath的写法不唯一):

  • serial_number序号
  • movie_name电影名
  • introduction介绍
  • rating_num星级
  • comment_num评论数
  • quote描述

//div[@class="article"]//ol[@class="grid_view"]/li基础上分别为:

div[@class="item"]//em/text()
div[@class="info"]//div[@class="hd"]//span[@class="title"][1]//text()
div[@class="info"]//div[@class="bd"]//p[1]//text()
div[@class="info"]//div[@class="bd"]//span[@class="rating_num"]//text()
div[@class="info"]//div[@class="bd"]//div[@class="star"]//span[4]//text()
div[@class="info"]//div[@class="bd"]//p[@class="quote"]//span//text()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

获取当前页面信息后,需要进行翻页,所以需要定位“后页”。
在这里插入图片描述
通过XPath进行定位,输入//span[@class="next"]//link//@href,可以获得一个结果?start=25&filter=,说明XPath输入的内容正确。

2.3 douban_spider.py编写

根据上面的规则修改douban_spider代码:

import scrapy
from items import DoubanItem

class DoubanSpiderSpider(scrapy.Spider):
    name = 'douban_spider'    # 爬虫名,该名字必须是唯一的,不可以为不同的Spider设定相同的名字。
    allowed_domains = ['movie.douban.com']  # 允许的域名,在这个域名内进行爬取
    start_urls = ['http://movie.douban.com/top250']  # 入口域名,扔到调度器中,包含了Spider在启动时进行爬取的url列表。

    # 默认解析方法
    def parse(self, response):
        # print(response.text)
        # 循环电影条数
        movie_list = response.xpath('//div[@class="article"]//ol[@class="grid_view"]//li')
        for i_item in movie_list:
            # 创建DoubanItem类,写详细的XPath并进行数据解析
            douban_item = DoubanItem()
            # 获取序号
            douban_item['serial_number'] = i_item.xpath(
                './/div[@class="item"]//em/text()').extract_first()  # 解析第一个数据
            # 获取电影名
            douban_item['movie_name'] = i_item.xpath(
                './/div[@class="info"]//div[@class="hd"]//span[@class="title"][1]//text()').extract_first()
            # 获取介绍
            content = i_item.xpath(
                './/div[@class="info"]//div[@class="bd"]//p[1]//text()').extract()
            for i_content in content:
                content_s = "".join(i_content.split())
                douban_item['introduction'] = content_s
            # 获取星级
            douban_item['rating_num'] = i_item.xpath(
                './/div[@class="info"]//div[@class="bd"]//span[@class="rating_num"]//text()').extract_first()
            # 获取评论数
            douban_item['comment_num'] = i_item.xpath(
                './/div[@class="info"]//div[@class="bd"]//div[@class="star"]//span[4]//text()').extract_first()
            # 获取描述
            douban_item['quote'] = i_item.xpath(
                './/div[@class="info"]//div[@class="bd"]//p[@class="quote"]//span//text()').extract_first()

            # print(douban_item)
            # 将数据yield到piplines里面
            yield douban_item  # 进入到pipelines

        # 解析下一页规则,取后页的XPath
        next_link = response.xpath('//span[@class="next"]//link//@href').extract()
        if next_link:  # 判断是否到最后一页
            next_link = next_link[0]
            yield scrapy.Request("http://movie.douban.com/top250"+next_link, callback=self.parse)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

运行main.py,获取相应的信息:
在这里插入图片描述

2.4 数据保存

2.4.1 json格式

首先需要在pipelines.py内定义保存格式:

import json

class JsonPipeline:
    def __init__(self):
        self.file = open('top250.json', 'wb')

    def process_item(self, item, spider):
        line = json.dumps(dict(item), ensure_ascii=False) + "\n"  # ensure_ascii=False 中文不乱码
        print(line)
        self.file.write(line.encode('utf-8'))
        return item
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

再修改settings.py文件,找到ITEM_PIPELINES选项:

ITEM_PIPELINES = {
    'douban.pipelines.JsonPipeline': 300
}
  • 1
  • 2
  • 3

运行main.py记可得到top250.json
在这里插入图片描述

2.4.2 xls文件

首先需要在pipelines.py内定义保存格式:

import xlwt

class CsvPipeline:
    def __init__(self):
        self.book = xlwt.Workbook(encoding='utf-8')
        self.sheet = self.book.add_sheet('top250')
        self.sheet.write(0, 0, 'serial_number')
        self.sheet.write(0, 1, 'movie_name')
        self.sheet.write(0, 2, 'introduction')
        self.sheet.write(0, 3, 'rating_num')
        self.sheet.write(0, 4, 'comment_num')
        self.sheet.write(0, 5, 'quote')
        self.row = 1

    def process_item(self, item, spider):
        self.sheet.write(self.row, 0, item['serial_number'])
        self.sheet.write(self.row, 1, item['movie_name'])
        self.sheet.write(self.row, 2, item['introduction'])
        self.sheet.write(self.row, 3, item['rating_num'])
        self.sheet.write(self.row, 4, item['comment_num'])
        self.sheet.write(self.row, 5, item['quote'])

        self.row += 1
        self.close_file(item)

    def close_file(self, item):
        self.book.save('top250.xls')
        return item
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

再修改settings.py文件,找到ITEM_PIPELINES选项:

ITEM_PIPELINES = {
    'douban.pipelines.CsvPipeline': 300
}
  • 1
  • 2
  • 3

运行main.py记可得到top250.xls
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/141390
推荐阅读
相关标签
  

闽ICP备14008679号