Scrapy爬虫(4)爬取豆瓣电影Top250图片

  在用Python的urllib和BeautifulSoup写过了很多爬虫之后,本人决定尝试著名的Python爬虫框架——Scrapy.
  本次分享将详细讲述如何利用Scrapy来下载豆瓣电影Top250, 主要解决的问题有:

  • 如何利用ImagesPipeline来下载图片
  • 如何对下载后的图片重命名,这是因为Scrapy默认用Hash值来保存文件,这并不是我们想要的

  首先我们要爬取的豆瓣电影Top250网页截图如下:


豆瓣电影Top250网页

  网页的结构并不复杂,所以,我们决定把所有的250部电影的图片都下载下来。接下来,就开始我们的Scrapy之旅啦~~
  首先我们新建一个Scrapy项目,叫做doubanMovie.

scrapy startproject doubanMovie

该项目的文件树形结构如下:


文件树形结构

  修改items.py如下:

# -*- coding: utf-8 -*-
import scrapy

class DoubanmovieItem(scrapy.Item):
    # two items: url and name of image
    url = scrapy.Field()
    img_name = scrapy.Field()

这是我们用来存放图片的url和name的部分。

  接着,在spiders文件夹下,新建爬虫(Spider)文件:doubanMovieSpider.py, 文件代码如下:

import scrapy
from scrapy.spiders import Spider  
from scrapy.selector import Selector  
from doubanMovie.items import DoubanmovieItem

class movieSpider(Spider):
    # name of Spider  
    name = "movie"
    #start urls
    start_urls = ["https://movie.douban.com/top250"] 
    for i in range(1,10):
        start_urls.append("https://movie.douban.com/top250?start=%d&filter="%(25*i))

    #parse function
    def parse(self, response):

        item = DoubanmovieItem()
        sel = Selector(response)
        images = sel.xpath('//*[@id="content"]/div/div[1]/ol/li')

        item['url'] = [] 
        item['img_name'] = []
        # append the url and name of the image in item
        for image in images:
            # extract url and name of the image   
            site = image.xpath('div/div[1]/a/img/@src').extract_first()
            img_name = image.xpath('div/div[1]/a/img/@alt').extract_first()

            item['url'].append(site)
            item['img_name'].append(img_name)

        yield item

该部分代码主要利用xpath来提出网页中的电影图片的url和name,并添加到item中。
  为了能够对下载后的图片进行重命名,我们需要修改pipeline.py文件,代码如下:

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

from scrapy.pipelines.images import ImagesPipeline
from scrapy.http import Request 

class DoubanmoviePipeline(object):
    def process_item(self, item, spider):
        return item

class MyImagesPipeline(ImagesPipeline):
    # yield meta for file_path() function
    def get_media_requests(self, item, info): 
        for url in item['url']: 
            yield Request(url, meta={'item': item, 'index':item['url'].index(url)})

    # rename the image
    def file_path(self, request, response=None, info=None):
        item = request.meta['item']
        index = request.meta['index']

        image_name = item['img_name'][index]
        return 'full/%s.jpg' % (image_name)

在这儿我们添加了MyImagesPipeline类,主要目的是用来对下载后的图片进行重命名。
  最后一步,也是关键的一步,就是修改settings.py文件,将其中的ROBOTSTXT_OBEY设置为False, 这是为了防止爬虫被禁,并且添加以下代码:

USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0"

ITEM_PIPELINES {'doubanMovie.pipelines.DoubanmoviePipeline': 2,  
                'doubanMovie.pipelines.MyImagesPipeline':1 }

IMAGES_URLS_FIELD = 'url'
IMAGES_STORE = r'.'

在上面的代码中,我们设置了USER_AGENT, 这是为了在Linux系统中模拟浏览器的设置,读者可以根据自己的系统和浏览器来设置不同的USER_AGENT. 同时, 我们又加了ITEM_PIPELINES管道和图片的保存路径。

  一切就绪,我们就可以运行爬虫啦。切换到spiders文件夹下,输入scrapy list可以查看爬虫的名字,输入scrapy crawl movie即可运行爬虫。


查看和运行爬虫

  movie爬虫的运行结果如下:

爬虫运行结果

该爬虫下载了250个文件,用时约13秒,效率惊人啊!
  下载后的图片保存在当前文件夹(spiders)下的full文件夹下,我们来看一下里面的内容:

下载图片

  Surprise!Wonderful! 里面有没有你喜欢的电影呢?

  本项目的Github地址为 https://github.com/percent4/doubanMovieSpider, 欢迎大家访问哦~~

注意:本人现已开通两个微信公众号: 因为Python(微信号为:python_math)以及轻松学会Python爬虫(微信号为:easy_web_scrape), 欢迎大家关注哦~~

### 使用 Scrapy 爬取豆瓣电影 Top 250 数据 #### 构建 Scrapy 项目 要使用 Scrapy 框架爬取豆瓣电影 Top 250 数据,首先需要安装 Scrapy 并创建一个新的 Scrapy 项目。可以通过以下命令完成这些操作: ```bash pip install scrapy scrapy startproject douban_movie ``` 这将在当前目录下生成一个名为 `douban_movie` 的项目文件夹。 --- #### 配置 Spider 文件 进入项目后,通过以下命令生成一个 Spider 文件来定义具体的爬取逻辑: ```bash cd douban_movie scrapy genspider top250 movie.douban.com ``` 此命令会在 `spiders` 目录下生成一个名为 `top250.py` 的 Python 文件。以下是该文件的一个基本实现示例: ```python import scrapy class Top250Spider(scrapy.Spider): name = 'top250' allowed_domains = ['movie.douban.com'] start_urls = ['https://movie.douban.com/top250'] def parse(self, response): movies = response.css('div.item') for movie in movies: title = movie.css('.title::text').get() rating = movie.css('.rating_num::text').get() quote = movie.css('span.inq::text').get() yield { 'title': title, 'rating': rating, 'quote': quote } next_page = response.css('link.next::attr(href)').get() if next_page is not None: yield response.follow(next_page, self.parse) ``` 这段代码实现了以下几个功能: - 定义了一个名为 `top250` 的 Spider[^1]。 - 设置了允许访问的域名以及起始 URL。 - 提取每部电影的名称 (`title`)、评分 (`rating`) 和简介 (`quote`)。 - 自动处理分页,当存在下一页时继续请求新的页面[^3]。 --- #### 处理反机制 豆瓣网站可能存在一定的反措施,因此需要注意以下几点以提高成功率: 1. **设置 User-Agent** 修改项目的 `settings.py` 文件,指定合法的浏览器标识符: ```python USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' ``` 2. **启用延迟下载** 同样在 `settings.py` 中配置下载间隔时间,避免频繁请求触发封禁: ```python DOWNLOAD_DELAY = 2 ``` 3. **添加代理池(可选)** 如果遇到 IP 封禁问题,可以引入第三方库如 `scrapy-proxies` 来动态切换代理地址。 --- #### 存储抓取结果 Scrapy 支持多种数据导出方式,例如 JSON、CSV 或 MySQL 数据库。以下是几种常见的存储方法: ##### 导出为 JSON 文件 执行以下命令即可将抓取的结果保存为 JSON 文件: ```bash scrapy crawl top250 -o top250.json ``` ##### 导出为 CSV 文件 如果希望以表格形式查看数据,则可以选择导出为 CSV 格式: ```bash scrapy crawl top250 -o top250.csv ``` ##### 存入 MySQL 数据库 为了更灵活地管理和查询数据,还可以将其存入关系型数据库中。需先修改 `pipelines.py` 文件并更新 `settings.py` 配置项。具体步骤如下: 1. 编辑 `pipelines.py` 添加自定义管道类: ```python import mysql.connector class DoubanMoviePipeline: def __init__(self): self.conn = mysql.connector.connect( host='localhost', user='root', password='your_password', database='movies' ) self.cursor = self.conn.cursor() self.create_table() def create_table(self): self.cursor.execute(""" CREATE TABLE IF NOT EXISTS top250 ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255), rating FLOAT, quote TEXT ) """) def process_item(self, item, spider): self.cursor.execute(""" INSERT INTO top250 (title, rating, quote) VALUES (%s, %s, %s) """, (item['title'], item['rating'], item['quote'])) self.conn.commit() return item def close_spider(self, spider): self.cursor.close() self.conn.close() ``` 2. 更新 `settings.py` 开启管道支持: ```python ITEM_PIPELINES = {'douban_movie.pipelines.DoubanMoviePipeline': 300} ``` 之后运行爬虫程序时会自动将数据写入 MySQL 表格中[^2]。 --- #### 测试与调试 在正式部署前建议先测试单个页面的内容提取效果。可以在终端输入以下指令启动交互模式: ```bash scrapy shell https://movie.douban.com/top250 ``` 利用返回的对象验证 CSS/XPath 表达式的准确性,确保字段定位无误后再投入批量采集阶段。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值