资讯专栏INFORMATION COLUMN

scrapy入门教程——爬取豆瓣电影Top250!

senntyou / 3022人阅读

摘要:注意爬豆爬一定要加入选项,因为只要解析到网站的有,就会自动进行过滤处理,把处理结果分配到相应的类别,但偏偏豆瓣里面的为空不需要分配,所以一定要关掉这个选项。

本课只针对python3环境下的Scrapy版本(即scrapy1.3+)

选取什么网站来爬取呢?

对于歪果人,上手练scrapy爬虫的网站一般是官方练手网站 http://quotes.toscrape.com

我们中国人,当然是用豆瓣Top250啦!https://movie.douban.com/top250

第一步,搭建准备

为了创造一个足够干净的环境来运行scrapy,使用virtualenv是不错的选择。

>>> mkdir douban250 && cd douban250
>>> virtualenv -p python3.5 doubanenv

首先要保证已经安装有virtualenv和python3.x版本,上面命令为创建python3.5环境的virtualenv

virtualenv教程:廖雪峰python教程-virtualenv

开启virtualenv,并安装scrapy

>>> source doubanenv/bin/activate
>>> pip install scrapy

使用scrapy初始化项目一个项目,比如我们命名为douban_crawler

>>> scrapy startproject douban_crawler

这时生成了一个目录结构

douban_crawler/
    douban.cfg
    douban_crawler/
        __init__.py
        items.py
        middlewares.py
        piplines.py
        setting.py

并且命令行会给你一个提示:

You can start your first spider with:
    cd douban_crawler
    scrapy genspider example example.com

按提示执行这两步吧!

>>> cd douban_crawler
>>> scrapy genspider douban movie.douban.com/top250

genspider后目录结构中增加了spider目录

douban_crawler/
    douban.cfg
    douban_crawler/
        spiders/
            __init__.py
            douban.py
        __init__.py
        items.py
        middlewares.py
        piplines.py
        setting.py
在pycharm中设置好项目

首先,在pycharm中打开douban_crawler/

然后设置pycharm的虚拟环境:

Perference > Project:douban_crawler > Project Interpreter
点击设置图标> Add Local > existing environment;把预置的python解析器,切换到刚刚创立的virtualenv下的doubanenv > bin > python3.5

开始爬取

准备工作完成,可以开始爬取了!

打开spiders/目录下的douban.py文件

# douban_crawler/ > spiders/ > douban.py

import scrapy

class DoubanSpider(scrapy.Spider):
    name = "douban"
    allowed_domains = ["movie.douban.com/top250"]
    start_urls = ["http://movie.douban.com/top250/"]

    def parse(self, response):
        pass

start_urls就是我们需要爬取的网址啦!

把start_urls中的http://movie.douban.com/top250/

改成https://movie.douban.com/top250/

接下来我们将改写parse()函数,进行解析。

解析豆瓣250条目

使用chrome或firefox浏览器打开https://movie.douban.com/top250/

使用右键菜单中的检查(inspect)分析元素,可以看出:

".item"包裹了一个个词条

每一个词条下面

".pic a img"的src属性包含了封面图片地址
".info .hd a"的src属性包含了豆瓣链接
".info .hd a .title"中的文字包含了标题,因为每个电影会有多个别名,我们只用取第一个标题就行了。
".info .bd .star .rating_num"包含了分数
".info .bd .quote span.inq"包含了短评

另外导演、年代、主演、简介等信息需要点击进入条目的才能爬取,我们先爬取以上五条信息吧!

按照刚刚的解析,填写parse()函数
# douban_crawler/ > spiders/ > douban.py

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

class DoubanSpider(scrapy.Spider):
    name = "douban"
    allowed_domains = ["movie.douban.com/top250"]
    start_urls = ["https://movie.douban.com/top250/"]

    def parse(self, response):
        items = response.css(".item")
        for item in items:
            yield {
                "cover_pic": item.css(".pic a img::attr(src)").extract_first(),
                "link": item.css(".info .hd a::attr(href)").extract_first(),
                "title": item.css(".info .hd a .title::text").extract_first(),
                "rating": item.css(".info .bd .star .rating_num::text").extract_first(),
                "quote": item.css(".info .bd .quote span.inq::text").extract_first()
            }

.css()运行类似于jquery或pyquery的解析器,但它可以用::text或::attr(href)来直接获取属性或文字,应当说比jquery解析器还要更方便。

当然,.css只能返回一个对象,而需要具体的文字或属性,则需要.extract()或.extract_first()

其中.extract()返回所有符合条件的文字或属性数组,而.extract_first()只返回查询到的第一条文字或属性。

在shell里验证解析语句是否正确

这里我们需要给大家一个窍门,就是先用shell验证刚刚写的css对不对

在pycharm窗口左下方打开terminal
命令行输入:

>>> scrapy shell https://movie.douban.com/top250

会出来一堆的返回信息,最后会出来一堆提示

[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    
[s]   item       {}
[s]   request    
[s]   response   <403 https://movie.douban.com/top250>
[s]   settings   
[s]   spider     
[s] Useful shortcuts:
[s]   fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s]   fetch(req)                  Fetch a scrapy.Request and update local objects 
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser

我们看到response一项

——什么?返回的403错误?

原来我们爬取豆瓣没有设置User-Agent请求头,而豆瓣不接受无请求头的Get请求,最终返回了403错误。

这时赶紧在settings.py里面加入一行

#  spider_crawler/ > settings.py

USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36" 

保存文件后,重新运行

>>> scrapy shell https://movie.douban.com/top250

提示:

[s]   response   <200 https://movie.douban.com/top250>

这时就可以开始检验刚刚的解析语句能不能获得想要的结果了:

response.css(".item")

返回了一个对象数组,我们取其中的第一个selector

>>> items = response.css(".item")
>>> item = item[0]

#把cover_pic对应的解析语句拷贝过来
>>> item.css(".pic a img::attr(src)").extract_first()

返回

"https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg"

即证明解析语句正确,其它的四项可以一一验证

>>> item.css(".pic a img::attr(src)").extract_first()
"https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg"
>>> item.css(".info .hd a::attr(href)").extract_first()
"https://movie.douban.com/subject/1292052/"
>>> item.css(".info .hd a .title::text").extract_first()
"肖申克的救赎"
>>> item.css(".info .bd .star .rating_num::text").extract_first()
"9.6"
>>> item.css(".info .bd .quote span.inq::text").extract_first()
"希望让人自由。"

这时候用exit()退出shell
再运行爬虫

>>> scrapy crawl douban

就可以看到解析后的数据输出了!

翻页爬取全部250条数据

刚刚我们初步爬取了一下,但这一页只显示25条,如何通过翻页爬到全部250条呢?

通过chrome浏览器的“检查”功能,我们找到豆瓣页面上的“下页”所对应的链接:

response.css(".paginator .next a::attr(href)")

现在我们改写一个douban.py

# douban_crawler/ > spiders/ > douban.py
class DoubanSpider(scrapy.Spider):
    name = "douban"
    allowed_domains = ["movie.douban.com/top250"]
    start_urls = ["https://movie.douban.com/top250"]

    def parse(self, response):
        items = response.css(".item")
        for item in items:
            yield {
                "cover_pic": item.css(".pic a img::attr(src)").extract_first(),
                "link": item.css(".info .hd a::attr(href)").extract_first(),
                "title": item.css(".info .hd a .title::text").extract_first(),
                "rating": item.css(".info .bd .star .rating_num::text").extract_first(),
                "quote": item.css(".info .bd .quote span.inq::text").extract_first()
            }
        next_page = response.css(".paginator .next a::attr(href)").extract_first()
        if next_page:
            next_page_real = response.urljoin(next_page)
            yield scrapy.Request(next_page_real, callback=self.parse,dont_filter=True)

以上通过response.urljoin()返回了拼接后的真实url
然后通过一个递归返回Request对象,遍历了所有的页面。

注意!爬豆爬一定要加入dont_filter=True选项,因为scrapy只要解析到网站的Url有"filter=",就会自动进行过滤处理,把处理结果分配到相应的类别,但偏偏豆瓣url里面的filter为空不需要分配,所以一定要关掉这个选项。

这时再运行一次爬虫

>>> scrapy crawl douban

250条数据已经爬取出来啦!

存储数据到文件

很简单,运行爬虫时加个-o就输出啦!

>>> scrapy crawl douban -o douban.csv

于是你看到当前目录下多了一个.csv文件,存储的正是我们想要的结果!

你也可以用 .json .xml .pickle .jl 等数据类型存储,scrapy也是支持的!

利用Items把爬到的数据结构化

Scrapy的Item功能很类似于Django或其它mvc框架中的model作用,即把数据转化成固定结构,这样才能便出保存和展示。

我们打开 items.py文件,如下定义一个名为DoubanItem的数据类型。

# douban_clawler > items.py
import scrapy

class DoubanItem(scrapy.Item):
    title = scrapy.Field()
    link = scrapy.Field()
    rating = scrapy.Field()
    cover_pic = scrapy.Field()
    quote = scrapy.Field()

有了DoubanItem后,就可以改造douban.py里面的parse函数,使爬取的信息全部转化为Item形式啦

# -*- coding: utf-8 -*-
import scrapy
from douban_crawler.items import DoubanItem

class DoubanSpider(scrapy.Spider):
    name = "douban"
    allowed_domains = ["movie.douban.com/top250"]
    start_urls = ["https://movie.douban.com/top250"]

    def parse(self, response):
        items = response.css(".item")
        for item in items:
            yield DoubanItem({
                "cover_pic": item.css(".pic a img::attr(src)").extract_first(),
                "link": item.css(".info .hd a::attr(href)").extract_first(),
                "title": item.css(".info .hd a .title::text").extract_first(),
                "rating": item.css(".info .bd .star .rating_num::text").extract_first(),
                "quote": item.css(".info .bd .quote span.inq::text").extract_first()
            })

        next_page = response.css(".paginator .next a::attr(href)").extract_first()
        if next_page:
            next_page_real = response.urljoin(next_page)
            yield scrapy.Request(next_page_real, callback=self.parse,dont_filter=True)

非常简单,只修改了两行:

引入DoubanItem

原来yield的一个dict格式,现在直接在DoubanItem中传入dict就可以把dict转化成DoubanItem对象了!

现在你可以scrapy crawl douban再试一次爬取,看是不是已经转换成了DoubanItem形式了?

存储数据到MongoDB

有了DoubanItem数据结构,我们就可以保存进MongoDB啦!

保存到MongoDB,我们需要用到pipline组件,没错,就是上面那一堆文件中的piplines.py

之前我们确保两件事:

mongodb服务已经开启。如果没有开启请sudo mongod开启本地。

pymongo包已安装。如果没有安装请pip install pymongo

使用pipline,请记住四个字!

启!

(开启爬虫)对应于open_spider,在spider开启时调用

在这里面启动mongodb

承!

(承接爬取任务)对应于from_clawler,它有几个特点:

它是类对象,所以必须加上@classmethod。

只要有这个函数,它就一定会被调用。

它必须返回我们Pipline本身对象的实例。

它有进入Scrapy所有核心组件的能力,也就是说可以通过它访问到settings对象。

转!

(转换对象)对应于process_item,它有几个特点:

必须返回Item对象或raise DropItem()错误

在这个函数内将传入爬取到的item并进行其它操作。

合!

(闭合爬虫)于应于close_spider,在spider关闭是调用

我们可以在这个函数内关闭MongoDB

有了以上知道,我们上代码!

# douban_crawler > piplines.py
import pymongo


class DoubanCrawlerPipeline(object):
    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db

    def open_spider(self, spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            mongo_uri = crawler.settings.get("MONGO_URI"),
            mongo_db = crawler.settings.get("MONGO_DB")
        )

    def process_item(self, item, spider):
        self.db["douban250"].insert_one(dict(item))
        return item

    def close_spider(self, spider):
        self.client.close()

同时在setting中添加MONGODB的配置

MONGO_URI = "localhost"
MONGO_DB = "douban"

还有非常重要的一步!
在setting中打开pipline的注释!!

ITEM_PIPELINES = {
   "douban_crawler.pipelines.DoubanCrawlerPipeline": 300,
}
现在打开crawler
scrapy crawl douban

爬到的信息已经保存到数据库了!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41038.html

相关文章

  • scrapy入门豆瓣电影top250爬取

    摘要:本文内容爬取豆瓣电影页面内容,字段包含排名,片名,导演,一句话描述有的为空,评分,评价人数,上映时间,上映国家,类别抓取数据存储介绍爬虫框架教程一入门创建项目创建爬虫注意,爬虫名不能和项目名一样应对反爬策略的配置打开文件,将修改为。 本文内容 爬取豆瓣电影Top250页面内容,字段包含:排名,片名,导演,一句话描述 有的为空,评分,评价人数,上映时间,上映国家,类别 抓取数据存储 ...

    xialong 评论0 收藏0
  • scrapy爬取豆瓣Top250电影

    摘要:这次我们爬取的内容准备步骤找到格式网页中需要爬取的数据的例如我们需要爬取图片的这里用的是不会用的同学请百度然后我们开始建立工程打开然后在你想要建立工程的目录下面输入就会自动建立一个工程然后去根目录建立一个去这个目录里建立一个注意这里的主爬虫 这次我们爬取的内容 showImg(https://segmentfault.com/img/bVSirX?w=1021&h=521); 准备步骤...

    codergarden 评论0 收藏0
  • Python爬虫 - scrapy - 爬取豆瓣电影TOP250

    摘要:前言新接触爬虫,经过一段时间的实践,写了几个简单爬虫,爬取豆瓣电影的爬虫例子网上有很多,但都很简单,大部分只介绍了请求页面和解析部分,对于新手而言,我希望能够有一个比较全面的实例。 0.前言 新接触爬虫,经过一段时间的实践,写了几个简单爬虫,爬取豆瓣电影的爬虫例子网上有很多,但都很简单,大部分只介绍了请求页面和解析部分,对于新手而言,我希望能够有一个比较全面的实例。所以找了很多实例和文...

    WalkerXu 评论0 收藏0
  • Java爬虫之下载IMDB中Top250电影的图片

    摘要:介绍在博客爬虫爬取豆瓣电影图片中我们利用的爬虫框架,将豆瓣电影图片下载到自己电脑上。那么,在的爬虫的也可以下载图片吗答案当然是肯定的在本次分享中,我们将利用的包和函数来实现图片的下载。 介绍   在博客:Scrapy爬虫(4)爬取豆瓣电影Top250图片中我们利用Python的爬虫框架Scrapy,将豆瓣电影Top250图片下载到自己电脑上。那么,在Java的爬虫的也可以下载图片吗?答...

    tianren124 评论0 收藏0
  • 零基础如何学爬虫技术

    摘要:楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,。本文来源知乎作者路人甲链接楚江数据提供网站数据采集和爬虫软件定制开发服务,服务范围涵盖社交网络电子商务分类信息学术研究等。 楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,http://www.chujiangdata.com。 第一:Python爬虫学习系列教程(来源于某博主:htt...

    KunMinX 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<