Scrapy框架爬虫案例

标签: Scrapy框架
39人阅读 评论(0) 收藏 举报
分类:

运行环境

 1. win10-64bit
 2. python 3.6(E:\ProgramData\Anaconda3\python.exe)

要爬取的部分为 
这里写图片描述

通过查看源代码,需要解析的代码就是这么一部分

<li>
  <div class="item">
    <div class="pic">
      <em class="">1</em>
        <a href="https://movie.douban.com/subject/1292052/">
        <img alt="肖申克的救赎" src="https://img3.doubanio.com/view/movie_poster_cover/ipst/public/p480747492.webp" class="">
        </a>
    </div>
    <div class="info">
      <div class="hd">
        <a href="https://movie.douban.com/subject/1292052/" class="">
          <span class="title">肖申克的救赎</span>
          <span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
          <span class="other">&nbsp;/&nbsp;月黑高飞(港)  /  刺激1995(台)</span>
        </a>
        <span class="playable">[可播放]</span>
      </div>
      <div class="bd">
        <p class="">
                          导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
                            1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
                        </p>
        <div class="star">
          <span class="rating5-t"></span>
          <span class="rating_num" property="v:average">9.6</span>
          <span property="v:best" content="10.0"></span>
          <span>854341人评价</span>
         </div>
         <p class="quote">
                                <span class="inq">希望让人自由。</span>
         </p>
       </div>
     </div>
   </div>
 </li>

创建项目

首先创建项目,cmd输入命令

scrapy startproject doubanmovie

创建项目成功,项目目录结构如下图 
目录结构                         

 1. 在spiders文件夹下编写自己的爬虫
 2. 在items中编写容器用于存放爬取到的数据
 3. 在pipelines中对数据进行各种操作
 4. 在settings中进行项目的各种设置。

爬虫定义

在spiders文件夹下创建文件MySpider.py 
在MySpider.py中创建类DoubanMovie继承自scrapy.Spider,同时定义以下属性和方法

  1. name : 爬虫的唯一标识符
  2. start_urls : 初始爬取的url列表
  3. parse() : 每个初始url访问后生成的Response对象作为唯一参数传给该方法,该方法解析返回的Response,提取数据,生成item,同时生成进一步要处理的url的request对象

其中parse()方法内使用scrapy框架中的Selector对Response对象进行解析。初步写好的代码如下:

import scrapy

class DoubanMovie(scrapy.Spider):
    # 爬虫唯一标识符
    name = 'doubanMovie'
    # 爬取域名
    allowed_domain = ['movie.douban.com']
    # 爬取页面地址
    start_urls = ['https://movie.douban.com/top250']

    def parse(self, response):
        print(response.body)

尝试运行一下发现出现403错误

这里写图片描述

说明爬虫被屏蔽了,那么就要增加一个请求头部,模拟浏览器登录。 
在settings文件中添加下面一行代码即可

USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'

接下来就可以成功运行。

Items定义

在doubanmovie文件夹下创建文件MovieItems.py,在该文件下编写存放爬取到的数据的容器 
创建类MovieItem继承自scrapy.Item,定义各种属性,语句类似以下

name = scrapy.Field()

写好的代码如下

import scrapy


class MovieItem(scrapy.Item):
    # 电影名字
    name = scrapy.Field()
    # 电影信息
    info = scrapy.Field()
    # 评分
    rating = scrapy.Field()
    # 评论人数
    num = scrapy.Field()
    # 经典语句
    quote = scrapy.Field()
    # 电影图片
    img_url = scrapy.Field()

数据解析

目前在MySpider.py文件中只获得了Response对象,要从中提取各种信息,不得不对Response对象进行解析,这里选择使用scrapy框架中的Selector。

首先初始化selector

selector = scrapy.Selector(response)

通过网站源代码解析出各个电影项

movies = selector.xpath('//div[@class="item"]')

再声明一个item用于存放电影信息

item = MovieItem()

之后对每个电影代码段进行解析,从中提取出所需信息存放在item中,由于电影名字有不同种语言类型,同时电影信息也不止一个字符串,如下

<span class="title">肖申克的救赎</span>
<span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
<p class="">
                          导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
                            1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
</p>

如果使用下列语句提取文本首个字符串会丢失信息

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

这里通过对list遍历获取全部信息

# 电影各种语言名字的列表
titles = movie.xpath('.//span[@class="title"]/text()').extract()

name = ''
for title in titles:
    name += title.strip()
item['name'] = name

此时parse()解析出各个电影信息,但是只是第一页,通过网页源代码发现

<span class="next">
  <link rel="next" href="?start=25&amp;filter="/>
  <a href="?start=25&amp;filter=" >后页&gt;</a>
</span>

可以获取下一页的url,将其提取出来,通过yield处理继续爬取下一页面的电影信息。由于最后一页中下一页为空,在此处加一个判断即可

next_page = selector.xpath('//span[@class="next"]/a/@href').extract()[0]
url = 'https://movie.douban.com/top250' + next_page
if next_page:
    yield scrapy.Request(url, callback=self.parse)

整个parse()方法代码如下

    def parse(self, response):
        selector = scrapy.Selector(response)
        # 解析出各个电影
        movies = selector.xpath('//div[@class="item"]')
        # 存放电影信息
        item = MovieItem()

        for movie in movies:

            # 电影各种语言名字的列表
            titles = movie.xpath('.//span[@class="title"]/text()').extract()
            # 将中文名与英文名合成一个字符串
            name = ''
            for title in titles:
                name += title.strip()
            item['name'] = name

            # 电影信息列表
            infos = movie.xpath('.//div[@class="bd"]/p/text()').extract()
            # 电影信息合成一个字符串
            fullInfo = ''
            for info in infos:
                fullInfo += info.strip()
            item['info'] = fullInfo
            # 提取评分信息
            item['rating'] = movie.xpath('.//span[@class="rating_num"]/text()').extract()[0].strip()
            # 提取评价人数
            item['num'] = movie.xpath('.//div[@class="star"]/span[last()]/text()').extract()[0].strip()[:-3]
            # 提取经典语句,quote可能为空
            quote = movie.xpath('.//span[@class="inq"]/text()').extract()
            if quote:
                quote = quote[0].strip()
            item['quote'] = quote
            # 提取电影图片
            item['img_url'] = movie.xpath('.//img/@src').extract()[0]

            yield item

        next_page = selector.xpath('//span[@class="next"]/a/@href').extract()[0]
        url = 'https://movie.douban.com/top250' + next_page
        if next_page:
            yield scrapy.Request(url, callback=self.parse)

数据存储

目前选择将数据存放在json文件中,在doubanmovie文件夹下创建文件MoviePipelines.py,编写类MoviePipeline,重写方法process_item(self, item, spider)用于处理数据。

import json

class MoviePipeline(object):
    def __init__(self):
        # 打开文件
        self.file = open('data.json', 'w', encoding='utf-8')

    # 该方法用于处理数据
    def process_item(self, item, spider):
        # 读取item中的数据
        line = json.dumps(dict(item), ensure_ascii=False) + "\n"
        # 写入文件
        self.file.write(line)
        # 返回item
        return item

    # 该方法在spider被开启时被调用。
    def open_spider(self, spider):
        pass
    # 该方法在spider被关闭时被调用。
    def close_spider(self, spider):
        self.file.close()

同时在settings文件中对pipeline进行注册

ITEM_PIPELINES = {
    'doubanmovie.MoviePipelines.MoviePipeline': 1,
}

其中数字1表示优先级,越低越优先。

存储完电影信息后,接下来存储电影图片。 
存放图片要用到scrapy框架中的ImagesPipeline 
在doubanmovie中新建文件ImgPipelines.py,编写类ImgPipeline继承自ImagesPipeline,然后重载方法

 1. get_media_requests(self, item, info)
 2. item_completed(self, results, item, info)

第一个方法从item中获得url并下载图片,返回一个Request对象,完成下载后,结果作为一个tuple(success, image_info_or_failure)发送给第二个方法,其中success是下载是否成功的bool,image_info_or_failure包括url、path和checksum三项。其中,path就是相对于IMAGES_STORE的路径(含文件名)。

整个文件代码如下

import scrapy
from scrapy.contrib.pipeline.images import ImagesPipeline
from scrapy.exceptions import DropItem


class ImagePipeline(ImagesPipeline):
    def get_media_requests(self, item, info):
        yield scrapy.Request(item['image_url'])

    def item_completed(self, results, item, info):
        image_url = [x['path'] for ok, x in results if ok]

        if not image_url:
            raise DropItem("Item contains no images")

        item['image_url'] = image_url
        return item

同时在settings文件中注册并设置下载目录

ITEM_PIPELINES = {
    'doubanmovie.MoviePipelines.MoviePipeline': 1,
    'doubanmovie.ImgPipelines.ImgPipeline': 100,
}
IMAGES_STORE = 'E:\\img\\'

然而在爬取过程中又出现问题:Forbidden by robots.txt 

在settings文件中将ROBOTSTXT_OBEY改为False,让scrapy不遵守robot协议,即可正常下载图片

新建begin.py文件,和scrapy.cfg同目录,内容如下,用于自动启动该项目。

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


第一个scrapy小项目完工,个人感觉难点在提取不同信息,以及针对爬取网站的各种保密机制采取措施。目前只是小探一下scrapy框架,其强大的特性待日后慢慢发现研究 。

github上代码路径:crawlDemo/doubanmovie


查看评论

创业,我为什么失败??? http://www.vchome.net

2002年11月至2003年5月,这段时间是阿蒙(http://www.vchome.net)的第一次创业,显然是失败的,深圳是个充满诱惑同时也充满陷阱的城市,年轻人需要这样的城市,创业者更需要这样的...
  • harrymeng
  • harrymeng
  • 2003-07-02 16:12:00
  • 4564

scrapy爬虫框架入门实例

scrapy爬虫框架入门实例关于如何安装scrapy框架,可以参考这篇文章 scrapy安装方法 初识scrapy框架,写个简单的例子帮助理解。强调一下,这里使用的是Python3.6例子的目标就...
  • zjiang1994
  • zjiang1994
  • 2016-10-10 21:22:14
  • 37662

Scrapy框架学习(三)----基于Scrapy框架实现的简单爬虫案例

Scrapy框架学习(三)—-Scrapy框架实现简单的爬虫程序前面2章讲解了Scrapy的基本内容,如:创建项目,配置settings.py,items,spider,item pipeline,s...
  • qq_33689414
  • qq_33689414
  • 2017-11-29 20:25:23
  • 362

Scrapy:Python的爬虫框架----原理介绍

Scrapy:Python的爬虫框架 网络爬虫,是在网上进行数据抓取的程序,使用它能够抓取特定网页的HTML数据。虽然我们利用一些库开发一个爬虫程序,但是使用框架可以大大提高效率,缩短开发时间...
  • wickedvalley
  • wickedvalley
  • 2016-07-22 18:18:41
  • 12698

爬虫试验 scrapy python2.7

  • 2016年06月17日 14:30
  • 17.3MB
  • 下载

[Python]网络爬虫(12):爬虫框架Scrapy的第一个爬虫示例入门教程

爬虫框架Scrapy的第一个爬虫示例入门教程。 我们使用dmoz.org这个网站来作为小抓抓一展身手的对象。 首先先要回答一个问题。 问:把网站装进爬虫里,总共分几步? 答案很简单,四步: ...
  • wxg694175346
  • wxg694175346
  • 2014-02-23 20:52:42
  • 190667

scrapy-1.4.pdf

  • 2017年11月22日 16:58
  • 1.15MB
  • 下载

scrapy爬虫框架学习入门教程及实例

Scrapy是一个基于Twisted,纯Python实现的爬虫框架,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非常之方便~ Scrapy 使用 Twisted...
  • jly58fgjk
  • jly58fgjk
  • 2016-06-05 22:06:57
  • 2119

基于scrapy框架爬虫学习小结

在之前完全没有接触过爬虫的我,甚至都不知道爬虫是何物,然而在数据挖掘课程第二次大作业中却要我们小组直接用scrapy框架做一个爬取朋友圈的爬虫,一接到作业的我们马上就懵逼了,别说是scrapy了,我们...
  • qq_29245097
  • qq_29245097
  • 2016-06-04 23:29:13
  • 10490

基于scrapy的爬虫小例子

  • 2017年08月29日 17:27
  • 13KB
  • 下载
    个人资料
    等级:
    访问量: 0
    积分: 150
    排名: 0
    文章分类
    文章存档