爬取豆瓣影评详细信息

使用scrapy框架进行下列爬虫任务

实验任务
(一)显示影片基本信息
访问豆瓣电影Top250(https://movie.douban.com/top250?start=0),获取每部电影的中文片名、排名、评分及其对应的链接,按照“排名-中文片名-评分-链接”的格式显示在屏幕上。
(二)存储影片详细信息
访问豆瓣电影Top250(https://movie.douban.com/top250?start=0),在问题1的基础上,获取每部电影的导演、编剧、主演、类型、上映时间、片长、评分人数以及剧情简介等信息,并将获取到的所有信息(一和二中得到的信息)保存至本地文件中。

此外,创建MySQL数据库movies,在该数据库中创建表格topMovies, 保存至本地文件的同时,将所有信息保存至表格topMovies中。

接下来按我的步骤:

1.新建工程 在PyCharm中新建一个名称为“scrapyProject”的工程。在“scrapyProject”工程底部打开Terminal窗口(如图3-8所示),在命令提示符后面输入命令“pip install scrapy”,下载Scrapy框架所需文件

 

2.继续输入命令“scrapy startproject movieScrapy”,创建Scrapy爬虫框架相关目录和文件。创建完成以后的具体目录结构如图3-9所示,这些目录和文件都是由Scrapy框架自动创建的,不需要手动创建。

在Scrapy爬虫程序目录结构中,各个目录和文件的作用如下: l Spiders目录:该目录下包含爬虫文件,需编码实现爬虫过程; l __init__.py:为Python模块初始化目录,可以什么都不写,但是必须要有; l items.py:模型文件,存放了需要爬取的字段; l middlewares.py:中间件(爬虫中间件、下载中间件),本案例中不用此文件; l pipelines.py:管道文件,用于配置数据持久化,例如写入数据库; l settings.py:爬虫配置文件; scrapy.cfg:项目基础设置文件,设置爬虫启用功能等。在本案例中不用此文件。

3.items.py的具体代码内容如下:

import scrapy


class MoviescrapyItem(scrapy.Item):
    # define the fields for your item here like:
    # 排名
    rank = scrapy.Field()
    # 中文片名
    title = scrapy.Field()
    # 评分
    rating = scrapy.Field()
    # 链接
    link = scrapy.Field()
    # 导演
    director = scrapy.Field()
    # 编剧
    writer = scrapy.Field()
    # 主演
    starring = scrapy.Field()
    # 类型
    genre = scrapy.Field()
    # 上映时间
    release_date = scrapy.Field()
    # 片长
    duration = scrapy.Field()
    # 评分人数
    rating_count = scrapy.Field()
    # 剧情简介
    description = scrapy.Field()

4.在Terminal窗口输入命令“cd movieScrapy”,进入对应的爬虫工程中,再输入命令“scrapy genspider movieSpider movie.douban.com”,这时,在spiders目录下会出现一个新的Python文件movieSpider.py,该文件就是我们要编写爬虫程序的位置。下面是poemSpider.py的具体代码:

import scrapy
from scrapy import Request
from ..items import MoviescrapyItem

class MovieSpider(scrapy.Spider):
    name = 'movieSpider'
    allowed_domains = ['movie.douban.com']
    start_urls = ['https://movie.douban.com/top250?start=0']

    def parse(self, response):
        # 提取每部电影信息
        movies = response.xpath('//div[@class="item"]')
        for movie in movies:
            item = MoviescrapyItem()
            item['rank'] = movie.xpath('div[@class="pic"]/em/text()').get()
            item['title'] = movie.xpath('div[@class="info"]/div[@class="hd"]/a/span[@class="title"]/text()').get()
            item['rating'] = movie.xpath('div[@class="info"]/div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()').get()
            item['link'] = movie.xpath('div[@class="info"]/div[@class="hd"]/a/@href').get()

            # 打印电影信息到屏幕上
            print(f"{item['rank']}-{item['title']}-{item['rating']}-{item['link']}")

            # 请求电影详情页并传递item
            yield Request(item['link'], callback=self.parse_detail, meta={'item': item})

        # 处理下一页
        next_page = response.xpath('//span[@class="next"]/a/@href').get()
        if next_page:
            yield Request(response.urljoin(next_page))

    def parse_detail(self, response):
        # 获取电影的详细信息
        item = response.meta['item']

        # 提取电影的详细信息
        info = response.xpath('//div[@id="info"]')

        # 导演
        director = response.xpath('.//span[contains(text(), "导演")]/following-sibling::span[1]/a/text()').getall()
        item['director'] = ','.join(director) if director else None

        # 编剧
        writer = response.xpath('.//span[contains(text(), "编剧")]/following-sibling::span[1]/a/text()').getall()
        item['writer'] = ','.join(writer) if writer else None

        # 主演
        actor = response.xpath('.//span[contains(text(), "主演")]/following-sibling::span[1]/a/text()').getall()
        item['starring'] = ','.join(actor[:10]) if actor else None  # 只保留前10个主演

        # 类型
        genre = response.xpath('.//span[contains(text(), "类型")]/following-sibling::span[1]/text()').get()
        item['genre'] = genre.strip() if genre else None

        # 上映时间
        release_date = response.xpath('.//span[contains(text(), "上映日期")]/following-sibling::span[1]/text()').get()
        item['release_date'] = release_date.strip() if release_date else None

        # 片长
        duration = response.xpath('.//span[contains(text(), "片长")]/following-sibling::span[1]/text()').get()
        item['duration'] = duration.strip() if duration else None

        # 评分人数
        rating_count = response.xpath('//span[@property="v:votes"]/text()').get()
        item['rating_count'] = rating_count.strip() if rating_count else None

        # 剧情简介
        description = response.xpath('//span[@property="v:summary"]/text()').get()
        item['description'] = description.strip() if description else None

        # 将item传递给Pipeline处理
        yield item

5.编写代码文件settings.py

BOT_NAME = 'movieScrapy'

SPIDER_MODULES = ['movieScrapy.spiders']
NEWSPIDER_MODULE = 'movieScrapy.spiders'
REQUEST_FINGERPRINTER_IMPLEMENTATION = '2.7'

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

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# 设置日志打印的等级
LOG_LEVEL = 'WARNING'

ITEM_PIPELINES = {
    'movieScrapy.pipelines.MoviescrapyPipeline': 1,
}


6.编写完成以后的pipelines.py代码如下(为了让你连接数据库):

from itemadapter import ItemAdapter
import json
import pymysql


class   MoviescrapyPipeline:
    def __init__(self):
        # 连接MySQL数据库
        self.connect = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            passwd='123456',  # 设置成用户自己的数据库密码
            db='movies',
            charset='utf8'
        )
        self.cursor = self.connect.cursor()

    def process_item(self, item, spider):
        # 写入数据库
        sql = '''INSERT INTO topMovies (movie_rank, title, rating, link, director, writer, starring, genre, release_date, duration, rating_count, description)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'''
        self.cursor.execute(sql, (
            item['rank'], item['title'], item['rating'], item['link'], item['director'],
            item['writer'], item['starring'], item['genre'], item['release_date'], item['duration'],
            item['rating_count'], item['description']
        ))
        self.connect.commit()
        return item

    def close_spider(self, spider):
        # 关闭数据库连接
        self.cursor.close()
        self.connect.close()

7.为了把爬取到的数据保存到MySQL数据库中,需要首先安装PyMySQL模块。 在PyCharm开发界面中点击“File->Settings…”,在打开的设置界面中,先点击“Project scrapyProject”,再点击“Python Interpreter”,会弹出的设置界面,点击界面底部的“+”。

8.在弹出的模块安装界面中,先在搜索框中输入“pymysql”,然后,在搜索到的结果中点击“PyMySQL”条目,最后,点击界面底部的“Install Package”,开始安装模块,如果安装成功,会出现的信息。

9.最后有两种执行Scrapy爬虫的方法,第一种是在Terminal窗口中输入命令“scrapy crawl movieSpider”,然后回车运行,等待几秒钟后即可完成数据的爬取。第二种是在poemScrapy目录下新建Python文件run.py(run.py应与scrapy.cfg文件在同一层目录下),并输入下面代码:

from scrapy import cmdline
cmdline.execute("scrapy crawl poemSpider".split())

在run.py代码区域点击鼠标右键,在弹出的菜单里选择“Run”运行代码,就可以执行Scrapy爬虫程序。执行成功以后,就可以看到生成的数据文件data.txt

 

这是mysql里的数据(注意mysql这个表得自己创,这个我没给出代码,可以参考我的表结构

  • 27
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值