V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
wsgzao
V2EX  ›  Python

Python 爬虫框架 Scrapy 入门与实践之爬取豆瓣电影 Top250 榜单

  •  
  •   wsgzao ·
    wsgzao · 2019-03-07 16:07:27 +08:00 · 3931 次点击
    这是一个创建于 2094 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    爬虫就是请求网站并提取数据的自动化程序,其中请求,提取,自动化是爬虫的关键。Python 作为一款出色的胶水语言自然成为了很多爬虫爱好者的首选,而使用 Python 开发的爬虫框架 Scrapy 当属目前最热门的解决方案之一。本文记录了目前网络上比较经典的 Scrapy 爬取豆瓣电影 Top250 榜单实践过程,作为 Python 爬虫框架 Scrapy 的入门案例。

    Python 爬虫框架 Scrapy 入门与实践之爬取豆瓣电影 Top250 榜单

    更新历史

    2019 年 03 月 02 日 - 初稿

    阅读原文 - https://wsgzao.github.io/post/scrapy/

    扩展阅读

    Scrapy - https://scrapy.org/


    什么是爬虫?

    网络爬虫(又被称为网页蜘蛛,网络机器人,在 FOAF 社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

    其实通俗的讲就是通过程序去获取 web 页面上自己想要的数据,也就是自动抓取数据

    爬虫可以做什么? 你可以爬去妹子的图片,爬取自己想看看的视频。。等等你想要爬取的数据,只要你能通过浏览器访问的数据都可以通过爬虫获取

    爬虫的本质是什么? 模拟浏览器打开网页,获取网页中我们想要的那部分数据

    浏览器打开网页的过程: 当你在浏览器中输入地址后,经过 DNS 服务器找到服务器主机,向服务器发送一个请求,服务器经过解析后发送给用户浏览器结果,包括 html,js,css 等文件内容,浏览器解析出来最后呈现给用户在浏览器上看到的结果

    所以用户看到的浏览器的结果就是由 HTML 代码构成的,我们爬虫就是为了获取这些内容,通过分析和过滤 html 代码,从中获取我们想要资源(文本,图片,视频.....)

    Python 爬虫的原理

    爬虫的基本流程

    发起请求 通过 HTTP 库向目标站点发起请求,也就是发送一个 Request,请求可以包含额外的 header 等信息,等待服务器响应

    获取响应内容 如果服务器能正常响应,会得到一个 Response,Response 的内容便是所要获取的页面内容,类型可能是 HTML,Json 字符串,二进制数据(图片或者视频)等类型

    解析内容 得到的内容可能是 HTML, 可以用正则表达式,页面解析库进行解析,可能是 Json, 可以直接转换为 Json 对象解析,可能是二进制数据,可以做保存或者进一步的处理

    保存数据 保存形式多样,可以存为文本,也可以保存到数据库,或者保存特定格式的文件

    什么是 Request,Response

    浏览器发送消息给网址所在的服务器,这个过程就叫做 HTPP Request

    服务器收到浏览器发送的消息后,能够根据浏览器发送消息的内容,做相应的处理,然后把消息回传给浏览器,这个过程就是 HTTP Response

    浏览器收到服务器的 Response 信息后,会对信息进行相应的处理,然后展示

    Request 中包含什么?

    请求方式

    主要有:GET/POST 两种类型常用,另外还有 HEAD/PUT/DELETE/OPTIONS GET 和 POST 的区别就是:请求的数据 GET 是在 url 中,POST 则是存放在头部

    GET: 向指定的资源发出 “显示” 请求。使用 GET 方法应该只用在读取数据,而不应当被用于产生 “副作用” 的操作中,例如在 Web Application 中。其中一个原因是 GET 可能会被网络蜘蛛等随意访问

    POST: 向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。

    HEAD:与 GET 方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中 “关于该资源的信息”(元信息或称元数据)。

    PUT:向指定资源位置上传其最新内容。

    OPTIONS:这个方法可使服务器传回该资源所支持的所有 HTTP 请求方法。用 '*' 来代替资源名称,向 Web 服务器发送 OPTIONS 请求,可以测试服务器功能是否正常运作。

    DELETE:请求服务器删除 Request-URI 所标识的资源。

    请求 URL

    URL,即统一资源定位符,也就是我们说的网址,统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

    URL 的格式由三个部分组成: 第一部分是协议 (或称为服务方式)。 第二部分是存有该资源的主机 IP 地址 (有时也包括端口号)。 第三部分是主机资源的具体地址,如目录和文件名等。

    爬虫爬取数据时必须要有一个目标的 URL 才可以获取数据,因此,它是爬虫获取数据的基本依据。

    请求头

    包含请求时的头部信息,如 User-Agent,Host,Cookies 等信息

    请求体 请求是携带的数据,如提交表单数据时候的表单数据( POST )

    Response 中包含了什么

    所有 HTTP 响应的第一行都是状态行,依次是当前 HTTP 版本号,3 位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。

    响应状态

    有多种响应状态,如:200 代表成功,301 跳转,404 找不到页面,502 服务器错误

    1xx 消息 —— 请求已被服务器接收,继续处理 2xx 成功 —— 请求已成功被服务器接收、理解、并接受 3xx 重定向 —— 需要后续操作才能完成这一请求 4xx 请求错误 —— 请求含有词法错误或者无法被执行 5xx 服务器错误 —— 服务器在处理某个正确请求时发生错误

    常见代码: 200 OK 请求成功 301 目标永久性转移 302 目标暂时性转移 400 Bad Request 客户端请求有语法错误,不能被服务器所理解 401 Unauthorized 请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用 403 Forbidden 服务器收到请求,但是拒绝提供服务 404 Not Found 请求资源不存在,eg:输入了错误的 URL 500 Internal Server Error 服务器发生不可预期的错误 503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常

    响应头

    如内容类型,类型的长度,服务器信息,设置 Cookie

    响应体

    最主要的部分,包含请求资源的内容,如网页 HTMl, 图片,二进制数据等

    能爬取什么样的数据

    网页文本:如 HTML 文档,Json 格式化文本等 图片:获取到的是二进制文件,保存为图片格式 视频:同样是二进制文件 其他:只要请求到的,都可以获取

    如何解析数据

    直接处理 Json 解析 正则表达式处理 BeautifulSoup 解析处理 PyQuery 解析处理 XPath 解析处理

    关于抓取的页面数据和浏览器里看到的不一样的问题

    出现这种情况是因为,很多网站中的数据都是通过 js,ajax 动态加载的,所以直接通过 get 请求获取的页面和浏览器显示的不同。

    如何解决 js 渲染的问题?

    分析 ajax Selenium/webdriver Splash PyV8,Ghost.py

    怎样保存数据

    文本:纯文本,Json,Xml 等

    关系型数据库:如 mysql,oracle,sql server 等结构化数据库

    非关系型数据库:MongoDB,Redis 等 key-value 形式存储

    Scrapy 简介

    Scrapy is an application framework for crawling web sites and extracting structured data which can be used for a wide range of useful applications, like data mining, information processing or historical archival.

    Scrapy 是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。

    Scrapy Tutorial https://docs.scrapy.org/en/latest/intro/overview.html

    Scrapy 架构

    Scrapy Engine 引擎负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。 详细内容查看下面的数据流 (Data Flow) 部分。

    此组件相当于爬虫的 “大脑”,是整个爬虫的调度中心。

    调度器 (Scheduler) 调度器从引擎接受 request 并将他们入队,以便之后引擎请求他们时提供给引擎。

    初始的爬取 URL 和后续在页面中获取的待爬取的 URL 将放入调度器中,等待爬取。同时调度器会自动去除重复的 URL (如果特定的 URL 不需要去重也可以通过设置实现,如 post 请求的 URL )

    下载器 (Downloader) 下载器负责获取页面数据并提供给引擎,而后提供给 spider。

    Spiders Spider 是 Scrapy 用户编写用于分析 response 并提取 item (即获取到的 item) 或额外跟进的 URL 的类。 每个 spider 负责处理一个特定 (或一些) 网站。

    Item Pipeline Item Pipeline 负责处理被 spider 提取出来的 item。典型的处理有清理、 验证及持久化 (例如存取到数据库中)。

    当页面被爬虫解析所需的数据存入 Item 后,将被发送到项目管道 (Pipeline),并经过几个特定的次序处理数据,最后存入本地文件或存入数据库。

    下载器中间件 (Downloader middlewares) 下载器中间件是在引擎及下载器之间的特定钩子 (specific hook),处理 Downloader 传递给引擎的 response。 其提供了一个简便的机制,通过插入自定义代码来扩展 Scrapy 功能。

    通过设置下载器中间件可以实现爬虫自动更换 user-agent、IP 等功能。

    Spider 中间件 (Spider middlewares) Spider 中间件是在引擎及 Spider 之间的特定钩子 (specific hook),处理 spider 的输入 (response) 和输出 (items 及 requests)。 其提供了一个简便的机制,通过插入自定义代码来扩展 Scrapy 功能。

    数据流 (Data flow)

    1. 引擎打开一个网站 (open a domain),找到处理该网站的 Spider 并向该 spider 请求第一个要爬取的 URL (s)。
    2. 引擎从 Spider 中获取到第一个要爬取的 URL 并在调度器 (Scheduler) 以 Request 调度。
    3. 引擎向调度器请求下一个要爬取的 URL。
    4. 调度器返回下一个要爬取的 URL 给引擎,引擎将 URL 通过下载中间件 (请求 (request) 方向) 转发给下载器 (Downloader)。
    5. 一旦页面下载完毕,下载器生成一个该页面的 Response,并将其通过下载中间件 (返回 (response) 方向) 发送给引擎。
    6. 引擎从下载器中接收到 Response 并通过 Spider 中间件 (输入方向) 发送给 Spider 处理。
    7. Spider 处理 Response 并返回爬取到的 Item 及 (跟进的) 新的 Request 给引擎。
    8. 引擎将 (Spider 返回的) 爬取到的 Item 给 Item Pipeline,将 (Spider 返回的) Request 给调度器。
    9. (从第二步) 重复直到调度器中没有更多地 request,引擎关闭该网站。

    Scrapy 爬取豆瓣电影 Top250 榜单

    https://docs.scrapy.org/en/latest/intro/tutorial.html

    工具和环境

    1. 语言: Python 3.7
    2. IDE: Pycharm
    3. 爬虫框架:Scrapy
    4. 浏览器: Google Chrome
    5. 浏览器插件: XPath Helper

    创建项目

    在开始爬取之前,首先要创建一个新的 Scrapy 项目。这里以爬取豆瓣电影 Top250 为例,进入你打算存储代码的目录中,运行下列命令:

    scrapy startproject douban
    

    该命令将会创建包含下列内容的 douban 目录:

    douban
    |-- __init__.py
    |-- __pycache__
    |   |-- __init__.cpython-37.pyc
    |   |-- items.cpython-37.pyc
    |   |-- pipelines.cpython-37.pyc
    |   `-- settings.cpython-37.pyc
    |-- items.py
    |-- middlewares.py
    |-- pipelines.py
    |-- settings.py
    `-- spiders
        |-- __init__.py
        |-- __pycache__
        |   |-- __init__.cpython-37.pyc
        |   `-- douban_spider.cpython-37.pyc
        `-- douban_spider.py
    
    3 directories, 13 files
    

    这些文件分别是:

    • scrapy.cfg: 项目的配置文件。
    • douban/: 该项目的 python 模块。之后您将在此加入代码。
    • douban/items.py: 项目中的 item 文件。定义我们所要爬取的信息的相关属性。
    • douban/pipelines.py: 项目中的 pipelines 文件。当数据被爬虫爬取下来后,它会被发送到 item pipelines 中,每个 item pipelines 组件(有时称为 “项目管道”)是一个实现简单方法的 Python 类。他们收到一个项目并对其执行操作,还决定该项目是否应该继续通过管道或被丢弃并且不再被处理。
    • douban/settings.py: 项目的设置文件。
    • douban/spiders/: 放置 spider 代码的目录。

    观察页面结构

    首先我们打开豆瓣电影 TOP250 的页面,通过观察页面决定让我们的爬虫获取每一部电影的排名、电影名称、评分和评分的人数。 https://movie.douban.com/top250

    运行 Chrome F12 开发者工具,使用选取工具选取整个电影的信息,可以发现,所有的信息都是放在单独的一个 li 标签中的,而且在 li 下还有一个 class 为 item 的 div 包裹着所有的信息。

    <li>
                <div class="item">
                    <div class="pic">
                        <em class="">1</em>
                        <a href="https://movie.douban.com/subject/1292052/">
                            <img width="100" alt="肖申克的救赎" src="https://img3.doubanio.com/view/photo/s_ratio_poster/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>1338863 人评价</span>
                            </div>
    
                                <p class="quote">
                                    <span class="inq">希望让人自由。</span>
                                </p>
                        </div>
                    </div>
                </div>
            </li>
    

    声明 Item

    什么是 Items 呢?官方文档 Items 定义如下:

    爬取的主要目标就是从非结构性的数据源提取结构性数据,例如网页。Scrapy spider 可以以 python 的 dict 来返回提取的数据。虽然 dict 很方便,并且用起来也熟悉,但是其缺少结构性,容易打错字段的名字或者返回不一致的数据,尤其在具有多个 spider 的大项目中。

    为了定义常用的输出数据,Scrapy 提供了 Item 类。Item 对象是种简单的容器,保存了爬取到得数据。 其提供了 类似于词典 (dictionary-like) 的 API 以及用于声明可用字段的简单语法。

    许多 Scrapy 组件使用了 Item 提供的额外信息: exporter 根据 Item 声明的字段来导出数据、 序列化可以通过 Item 字段的元数据 (metadata) 来定义、trackref 追踪 Item 实例来帮助寻找内存泄露 (see 使用 trackref 调试内存泄露) 等等。

    Item 使用简单的 class 定义语法以及 Field 对象来声明。我们打开 spider 目录下的 items.py 文件写入下列代码声明 Item:

    # -*- coding: utf-8 -*-
    
    # Define here the models for your scraped items
    #
    # See documentation in:
    # https://doc.scrapy.org/en/latest/topics/items.html
    
    import scrapy
    
    class DoubanItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        serial_number = scrapy.Field()
        movie_name = scrapy.Field()
        introduce = scrapy.Field()
        star = scrapy.Field()
        evaluate = scrapy.Field()
        describe = scrapy.Field()
    
    

    编写爬虫程序

    在编写代码前我们可以通过修改 settings.py 文件调整 user-agent 和其它参数

    # -*- coding: utf-8 -*-
    
    # Scrapy settings for douban project
    #
    # For simplicity, this file contains only settings considered important or
    # commonly used. You can find more settings consulting the documentation:
    #
    #     https://doc.scrapy.org/en/latest/topics/settings.html
    #     https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
    #     https://doc.scrapy.org/en/latest/topics/spider-middleware.html
    
    BOT_NAME = 'douban'
    
    SPIDER_MODULES = ['douban.spiders']
    NEWSPIDER_MODULE = 'douban.spiders'
    
    
    # Crawl responsibly by identifying yourself (and your website) on the user-agent
    USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
    
    # Obey robots.txt rules
    ROBOTSTXT_OBEY = False
    
    # Configure a delay for requests for the same website (default: 0)
    # See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
    # See also autothrottle settings and docs
    DOWNLOAD_DELAY = 0.5
    
    # Configure item pipelines
    # See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
    ITEM_PIPELINES = {
       'douban.pipelines.DoubanPipeline': 300,
    }
    
    mongo_host = '127.0.0.1'
    mongo_port = 27017
    mongo_db_name = 'douban'
    mongo_db_collection = 'douban_movie'
    

    在 spiders 文件夹下创建 douban_spider.py 文件

    在我们编写爬虫之前,先了解一下 scrapy 的爬取机制,scrapy 提取数据有自己的一套机制。它们被称作选择器 (seletors),因为他们通过特定的 XPath 或者 CSS 表达式来 “选择” HTML 文件中的某个部分。

    Xpath 学习教程 http://www.w3school.com.cn/xpath/index.asp

    XPath Helper https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl

    Scrapy xpath-tutorial https://doc.scrapy.org/en/xpath-tutorial/topics/xpath-tutorial.html

    # -*- coding: utf-8 -*-
    import scrapy
    from douban.items import DoubanItem
    
    class DoubanSpiderSpider(scrapy.Spider):
        name = 'douban_spider'
        allowed_domains = ['movie.douban.com']
        start_urls = ['https://movie.douban.com/top250']
    
        def parse(self, response):
            movie_list = response.xpath("//div[@class='article']//ol[@class='grid_view']/li")
            for i_item in movie_list:
                douban_item = DoubanItem()
                douban_item['serial_number'] = i_item.xpath(".//div[@class='item']//em/text()").extract_first()
                douban_item['movie_name'] = i_item.xpath(".//div[@class='info']/div[@class='hd']/a/span[1]/text()").extract_first()
                content = i_item.xpath(".//div[@class='info']//div[@class='bd']/p[1]/text()").extract()
                for i_content in content:
                    content_s = "".join(i_content.split())
                    douban_item['introduce'] = content_s
                douban_item['star'] =  i_item.xpath(".//span[@class='rating_num']/text()").extract_first()
                douban_item['evaluate'] = i_item.xpath(".//div[@class='star']//span[4]/text()").extract_first()
                douban_item['describe'] = i_item.xpath(".//p[@class='quote']//span/text()").extract_first()
                yield douban_item
            next_link = response.xpath("//span[@class='next']/link/@href").extract()
            if next_link:
                next_link = next_link[0]
                yield scrapy.Request("https://movie.douban.com/top250"+next_link,callback=self.parse)
    
    
    
    

    自动翻页 先别急着高兴,你难道没有发现一个问题吗?这样的话我们还是只能爬到当前页的 25 个电影的内容。怎么样才能把剩下的也一起爬下来呢?

    实现自动翻页一般有两种方法:

    1. 在页面中找到下一页的地址;
    2. 自己根据 URL 的变化规律构造所有页面地址。

    一般情况下我们使用第一种方法,第二种方法适用于页面的下一页地址为 JS 加载的情况。这次我们只说第一种方法。

    首先利用 Chrome 浏览器的开发者工具找到下一页的地址,然后在解析该页面时获取下一页的地址并将地址交给调度器 (Scheduler)

    运行爬虫

    scrapy crawl douban_spider

    scrapy crawl douban_spider -o douban.csv

    
    (venv)  wangao@wangao-MAC  ~/Documents/git/wangao/python3/scrapy/douban  python -V
    Python 3.7.1
    (venv)  wangao@wangao-MAC  ~/Documents/git/wangao/python3/scrapy/douban  scrapy crawl douban_spider -o douban.csv
    2019-03-02 15:37:56 [scrapy.utils.log] INFO: Scrapy 1.5.1 started (bot: douban)
    2019-03-02 15:37:56 [scrapy.utils.log] INFO: Versions: lxml 4.2.5.0, libxml2 2.9.8, cssselect 1.0.3, parsel 1.5.1, w3lib 1.19.0, Twisted 18.9.0, Python 3.7.1 (default, Nov  6 2018, 18:46:03) - [Clang 10.0.0 (clang-1000.11.45.5)], pyOpenSSL 18.0.0 (OpenSSL 1.1.0j  20 Nov 2018), cryptography 2.4.2, Platform Darwin-18.2.0-x86_64-i386-64bit
    2019-03-02 15:37:56 [scrapy.crawler] INFO: Overridden settings: {'BOT_NAME': 'douban', 'DOWNLOAD_DELAY': 0.5, 'FEED_FORMAT': 'csv', 'FEED_URI': 'douban.csv', 'NEWSPIDER_MODULE': 'douban.spiders', 'SPIDER_MODULES': ['douban.spiders'], 'USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'}
    2019-03-02 15:37:56 [scrapy.middleware] INFO: Enabled extensions:
    ['scrapy.extensions.corestats.CoreStats',
     'scrapy.extensions.telnet.TelnetConsole',
     'scrapy.extensions.memusage.MemoryUsage',
     'scrapy.extensions.feedexport.FeedExporter',
     'scrapy.extensions.logstats.LogStats']
    2019-03-02 15:37:56 [scrapy.middleware] INFO: Enabled downloader middlewares:
    ['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
     'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
     'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
     'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
     'scrapy.downloadermiddlewares.retry.RetryMiddleware',
     'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
     'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
     'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
     'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',
     'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
     'scrapy.downloadermiddlewares.stats.DownloaderStats']
    2019-03-02 15:37:56 [scrapy.middleware] INFO: Enabled spider middlewares:
    ['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
     'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
     'scrapy.spidermiddlewares.referer.RefererMiddleware',
     'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
     'scrapy.spidermiddlewares.depth.DepthMiddleware']
    2019-03-02 15:37:56 [scrapy.middleware] INFO: Enabled item pipelines:
    ['douban.pipelines.DoubanPipeline']
    2019-03-02 15:37:56 [scrapy.core.engine] INFO: Spider opened
    2019-03-02 15:37:56 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
    2019-03-02 15:37:56 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
    ^C2019-03-02 15:37:56 [scrapy.crawler] INFO: Received SIGINT, shutting down gracefully. Send again to force 
    2019-03-02 15:37:56 [scrapy.core.engine] INFO: Closing spider (shutdown)
    2019-03-02 15:37:58 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://movie.douban.com/top250> (referer: None)
    2019-03-02 15:37:58 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/top250>
    {'describe': '希望让人自由。',
     'evaluate': '1338863 人评价',
     'introduce': '1994/美国 /犯罪剧情',
     'movie_name': '肖申克的救赎',
     'serial_number': '1',
     'star': '9.6'}
    2019-03-02 15:37:58 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/top250>
    {'describe': '风华绝代。',
     'evaluate': '989216 人评价',
     'introduce': '1993/中国大陆香港 /剧情爱情同性',
     'movie_name': '霸王别姬',
     'serial_number': '2',
     'star': '9.6'}
    2019-03-02 15:37:58 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/top250>
    {'describe': '怪蜀黍和小萝莉不得不说的故事。',
     'evaluate': '1225142 人评价',
     'introduce': '1994/法国 /剧情动作犯罪',
     'movie_name': '这个杀手不太冷',
     'serial_number': '3',
     'star': '9.4'}
    2019-03-02 15:37:58 [scrapy.core.scraper] DEBUG: Scraped from <200 https://movie.douban.com/top250>
    {'describe': '一部美国近现代史。',
     'evaluate': '1054616 人评价',
     'introduce': '1994/美国 /剧情爱情',
     'movie_name': '阿甘正传',
     'serial_number': '4',
     'star': '9.4'}
    
    
    describe,evaluate,introduce,movie_name,serial_number,star
    希望让人自由。,1338863 人评价,1994/美国 /犯罪剧情,肖申克的救赎,1,9.6
    风华绝代。,989216 人评价,1993/中国大陆香港 /剧情爱情同性,霸王别姬,2,9.6
    怪蜀黍和小萝莉不得不说的故事。,1224747 人评价,1994/法国 /剧情动作犯罪,这个杀手不太冷,3,9.4
    一部美国近现代史。,1054616 人评价,1994/美国 /剧情爱情,阿甘正传,4,9.4
    最美的谎言。,617064 人评价,1997/意大利 /剧情喜剧爱情战争,美丽人生,5,9.5
    失去的才是永恒的。 ,993900 人评价,1997/美国 /剧情爱情灾难,泰坦尼克号,6,9.3
    最好的宫崎骏,最好的久石让。 ,981959 人评价,2001/日本 /剧情动画奇幻,千与千寻,7,9.3
    拯救一个人,就是拯救整个世界。,550815 人评价,1993/美国 /剧情历史战争,辛德勒的名单,8,9.5
    诺兰给了我们一场无法盗取的梦。,1067442 人评价,2010/美国英国 /剧情科幻悬疑冒险,盗梦空间,9,9.3
    

    结尾

    Scrapy 爬虫框架掌握好可以事半功倍,但是遇到简单的需求未必需要使用框架去解决。关于 IP 代理中间件,写入数据库,Web 前台展示等需求都是非常值得延伸的内容,希望大家通过爬虫豆瓣电影 Top250 这个入门项目开个学习的好头。

    11 条回复    2019-03-08 16:06:53 +08:00
    Leiothrix
        1
    Leiothrix  
       2019-03-07 17:22:25 +08:00   ❤️ 2
    老哥你得明白 V2 是个吹水的平台,跟博客论坛是不一样的,手动 doge。
    Youle
        2
    Youle  
       2019-03-07 18:01:41 +08:00
    留名 晚上看看
    enrolls
        3
    enrolls  
       2019-03-08 02:54:58 +08:00
    request + lxml 的事儿,xpath 还自动生成的。 毛胚代码 https://send.firefox.com/download/c431569c8f/#qvjxEU0M_7xm8N6X2W2ABw
    wsgzao
        4
    wsgzao  
    OP
       2019-03-08 10:03:01 +08:00
    @enrolls #3 厉害,我老婆是做金融的,他们组需要关心中国股票市场,我之前想尝试抓取上交所和深交所的最新上市公告信息,按公告时间,证券代码,公告标题,这三个简单的维度抓取入库,之后再按需求分组解析。可是学艺不精,第一步爬虫就失败了,尝试切换爬取巨潮资讯,但也没能解决,大神是否可以帮忙指点下方法

    http://www.sse.com.cn/disclosure/listedinfo/announcement/
    http://www.szse.cn/disclosure/listed/notice/
    sherlockwhite
        5
    sherlockwhite  
       2019-03-08 11:23:29 +08:00   ❤️ 1
    wsgzao
        6
    wsgzao  
    OP
       2019-03-08 12:03:14 +08:00
    @sherlockwhite #5 感谢分享,似乎被其他 V 友下载失效了。个人觉得金融行业其实有很多他们认为很困难,但对于 IT 行业来说很简单的操作。针对这个需求是否可以直接开源代码到 Github 上,做成一个通用的项目,不仅支持中国的上交所和深交所,未来还可以支持全球的主流交易所上市公告信息。
    hyc5312
        8
    hyc5312  
       2019-03-08 13:57:13 +08:00
    scrapy 架构很清晰,本人也基于 java 写了个爬虫框架,可以试用看看~ https://github.com/heyingcai
    wsgzao
        9
    wsgzao  
    OP
       2019-03-08 15:19:02 +08:00
    @sherlockwhite #7 非常感谢,我晚上带领我老婆一起学习下你的代码,然后趁热打铁继续把深交所的做出来,谢谢啦
    enrolls
        10
    enrolls  
       2019-03-08 15:25:09 +08:00   ❤️ 1
    做法的话,我理解为,可以基于模拟请求,或者基于页面。
    基于页面,则需要请求,解析,根据规则提取,入库,#3 是基于页面的做法,里面的根据规则提取。
    基于请求,则模拟请求,读 api,解析,入库。
    只求结果的话,建议基于请求,同样是毛胚代码 https://send.firefox.com/download/abf0ae7922/#J1hYI6yxvzXx4NI6bORVjQ
    wsgzao
        11
    wsgzao  
    OP
       2019-03-08 16:06:53 +08:00
    @enrolls #10 谢谢您花时间编码和回复解决问题的思路
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2414 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 01:00 · PVG 09:00 · LAX 17:00 · JFK 20:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.