Scrapy框架爬取豆瓣电影top250信息

点击上方蓝色小字,关注“涛哥聊Python

重磅干货,第一时间送达

作者:叶庭云

CSDN:https://blog.csdn.net/fyfugoyfa

一、分析网页

目标URL:https://movie.douban.com/top250?start=0&filter=

每一页有25条电影信息,总共10页。检查网页可以发现,每条电影的详细信息在 ol class="grid_view" 下的 li 标签里。

在这里插入图片描述

翻页查看网页可以发现URL变化的规律,在第 page 页,URL为:f'https://movie.douban.com/top250?start={(page-1) * 25} &filter='

在编写 scrapy 爬虫时,可以构造出 10 页的URL,生成10次请求。



二、scrapy爬虫

编写scrapy爬虫,电影信息保存到 csv 文件,电影海报保存到本地文件夹。

创建项目

scrapy startproject Douban_movie_top250
cd Douban_movie_top250
scrapy genspider Douban movie.douban.com

构造请求

Douban.py中定义 start_requests() 方法,爬取十页的电影信息,生成10次请求,代码如下:

    def start_requests(self):
        for i in range(10):
            url = f'https://movie.douban.com/top250?start={25 * i}&filter='
            yield Request(url=url, callback=self.parse)

编写 items.py

import scrapy


class DoubanMovieTop250Item(scrapy.Item):
 # 定义 Item 数据结构
    name = scrapy.Field()
    pic_link = scrapy.Field()
    rank = scrapy.Field()
    director_actor = scrapy.Field()
    info = scrapy.Field()
    rating_score = scrapy.Field()
    rating_num = scrapy.Field()
    introduce = scrapy.Field()

编写 Douban.py

Spider类定义了如何爬取某个(或某些)网站,包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(抓取item)

import scrapy
from scrapy import Request
from Douban_movie_top250.items import DoubanMovieTop250Item


class DoubanSpider(scrapy.Spider):
    name = 'Douban'
    allowed_domains = ['movie.douban.com']

    def start_requests(self):
        for i in range(10):
            url = f'https://movie.douban.com/top250?start={25 * i}&filter='
            yield Request(url=url, callback=self.parse)

    def parse(self, response, **kwargs):
     # Xpath定位提取数据  遍历  获取每一条电影的详细信息
        for li in response.xpath("//ol[@class='grid_view']/li"):
            item = DoubanMovieTop250Item()
            item['rank'] = li.xpath(".//div[@class='pic']/em/text()").extract_first()
            item['name'] = li.xpath(".//div[@class='hd']/a/span[@class='title']/text()").extract_first()
            item['pic_link'] = li.xpath(".//div[@class='pic']/a/img/@src").extract_first()
            item['info'] = li.xpath(".//div[@class='bd']/p/text()").extract()[1].strip()
            item['director_actor'] = li.xpath(".//div[@class='bd']/p/text()").extract_first().strip()
            item['rating_score'] = li.xpath(".//div[@class='star']/span[2]/text()").extract_first()
            item['rating_num'] = li.xpath(".//div[@class='star']/span[4]/text()").extract_first()
            item['introduce'] = li.xpath(".//p[@class='quote']/span/text()").extract_first()
            yield item

编写管道文件 pipelines.py

还要将电影海报一起下载下来,所以需要编写管道文件 pipelines.py,Scrapy 提供了专门处理下载的 Pipeline,包括文件下载和图片下载。下载文件和图片的原理与抓取页面的原理一样,因此下载过程支持异步和多线程,十分高效。

from scrapy.pipelines.images import ImagesPipeline  # scrapy图片下载器
from scrapy import Request
from scrapy.exceptions import DropItem


class DoubanMovieTop250Pipeline(ImagesPipeline):
    # 请求下载图片
    def get_media_requests(self, item, info):
        yield Request(item['pic_link'], meta={'name': item['name']})

    def item_completed(self, results, item, info):
        # 分析下载结果并剔除下载失败的图片
        image_paths = [x['path'] for ok, x in results if ok]
        if not image_paths:
            raise DropItem("Item contains no images")
        return item

    # 重写file_path方法,将图片以原来的名称和格式进行保存
    def file_path(self, request, response=None, info=None):
        name = request.meta['name']  # 接收上面meta传递过来的图片名称
        file_name = name + '.jpg'    # 添加图片后缀名
        return file_name

配置文件 settings.py

# settings.py

BOT_NAME = 'Douban_movie_top250'

SPIDER_MODULES = ['Douban_movie_top250.spiders']
NEWSPIDER_MODULE = 'Douban_movie_top250.spiders'

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 10

# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.25

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'Douban_movie_top250.pipelines.DoubanMovieTop250Pipeline': 300,
}
IMAGES_STORE = './Douban_pic'    # 图片保存路径

运行程序

# 切换路径到img_spider的目录
scrapy crawl Douban -o movies_info.csv

运行效果如下:

scrapy爬虫在 2020-08-28  16:56:14启动,输出了 Scrapy 的版本和一些配置信息,之后爬虫一边爬取一边下载,下载速度非常快。2020-08-28  16:56:45 scrapy爬虫完成了电影信息和海报的爬取。

运行结果如下:


三、处理数据

用scrapy框架爬取电影信息时,支持异步、并发,爬取效率很高,但输出到 CSV 文件里列名并没有按照 item 赋值时的顺序,每行的电影信息页没有按照排名排序,将数据处理一下并重新保存到Excel。

import pandas as pd


df4 = pd.read_csv('movies_info.csv')
cols = df4.columns[[5, 3, 0, 1, 6, 7, 2, 4]]  # 交换列的位置  自定义
new_df4 = df4[cols]
new_df4.sort_values(by='rank', inplace=True)  # 按排名排序
new_df4.to_excel('moives_info.xlsx', index=False)   # 重新保存到Excel

运行效果如下:


本文仅用于交流学习,未经作者允许,禁止转载,更勿做其他用途,违者必究。文章对你有所帮助的话,欢迎给个赞或者 star 呀,你的支持是对作者最大的鼓励,不足之处可以在评论区多多指正,交流学习呀。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值