moear-spider-zhihudaily

概览

该项目实现了基于 Scrapy 的爬虫功能,用于爬取知乎日报文章,供 MoEar 使用。

对于 MoEar 来说,并不强求爬虫插件使用何种技术实现,只要符合 moear-api-common 中定义的相关接口即可。

安装方法

您可以通过 pip 进行安装,本包仅在 Python 3.X 下测试通过:

pip install moear-spider-zhihudaily

项目结构

包路径说明如下:

.
├── __init__.py
├── assets                      # 资产路径,用来存储当前文章源的静态资源
│   ├── css
│   │   └── package.css         # 为打包时提供的该文章源的文章样式文件
│   └── images
│       ├── cv_zhihudaily.jpg   # 为打包时提供的书籍封面,600*800
│       └── mh_zhihudaily.gif   # 为打包时提供的书籍报头,600*60
├── crawler_script.py           # 用于提供可程序调用Scrapy的爬行类
├── entry.py                    # 实现接口定义的入口文件
├── items.py                    # Scrapy 的数据模型
├── middlewares.py              # Scrapy 的中间件
├── pipelines.py                # Scrapy 的流水线
├── settings.py                 # Scrapy 的参数设置
└── spiders                     # Scrapy 的具体爬虫实现路径
    ├── __init__.py
    └── zhihu_daily.py          # 知乎日报的爬虫主体

注意

开发时注意需要在 setup.py 中添加如下配置,以便 stevedore 加载该插件:

entry_points={
    'moear.spider': [
        'zhihu_daily = moear_spider_zhihudaily.entry:ZhihuDaily',
    ],
},

参考 stevedore 文档,将第三行内容替换为您的具体实现即可

业务流程

爬虫注册

MoEar 在启动阶段会加载所有 moear.spider 扩展插件,并通过调用其 ZhihuDaily.register() 方法获取到该爬虫的配置信息,并持久化到 DB 中。

注意

注意此方法会在 MoEar 每次启动时进行调用并更新配置,故在 DB 中修改相应值是没有意义的, DB 中的数据仅作为前端显示用(未出现的值不算,如:enabled,控制爬虫是否开启)

当前包的注册方法返回值用例,仅供参考:

{
    'name': 'zhihu_daily',
    'display_name': '知乎日报',
    'author': '小貘',
    'email': 'moore@moorehy.com',
    'description': '每天三次,每次七分钟。在中国,资讯类移动应用的人均阅读时长是 5 分钟,而在知乎日报,这个数字是 21',
    'meta': {
        'crawl_schedule': '0 23 * * *',
        'crawl_random_delay': '3600',
        'package_module': 'mobi',
        'language': 'zh-CN',
        'book_mode': 'periodical',
        'img_cover': '/path/to/moear_spider_zhihudaily/assets/images/cv_zhihudaily.jpg',
        'img_masthead': '/path/to/moear_spider_zhihudaily/assets/images/mh_zhihudaily.gif',
        'image_filter': '["zhihu.com/equation"]',
        'css_package': '/path/to/moear_spider_zhihudaily/assets/css/package.css'
    }
}
字段说明
name
唯一,作为存储到 DB 中数据模型的主键
display_name
唯一,作为书籍打包时的书籍名称显示
author
作为书籍打包时的作者显示,少年,留下你的大名吧,让每位阅读者都瞻仰一秒钟~~
email
邮箱地址,作为 MoEar 显示数据,方便联系到爬虫作者,提交 Bug
description
文章源描述,作为 MoEar 显示数据
meta

为用于控制爬取计划&打包业务的元数据

crawl_schedule
爬取计划任务,遵循标准 crontab 语法格式
crawl_random_delay

爬取任务随机延时最大时间,单位秒。会在 0 到该值间获取一个随机数值作为爬取前的延时。

主要考虑到防止被文章源服务器 Ban 掉 IP , 故在定点爬取计划任务触发后,再增加指定范围内的随机延时,以保安全。

package_module
指定该爬虫爬取的文章在打包时使用的打包模块名,如此处值为 mobi ,即 MoEar 会遍历 moear.package 入口中的 mobi 插件。作为打包工具传入文章数据列表
language
用于指定在生成书籍文件时指定的语言
book_mode

书籍模式,针对 Kindle 目前支持两种模式,periodicalbook

  1. periodical,期刊模式支持列表与宫格图的索引显示,但由于官方没有完整的说明文档,
    故很多功能的实现只能靠猜。。。
  2. book,书籍模式,官方有提供完整的用例,故支持较好,但没有索引显示,智能看蹩脚的目录
img_cover
当前文章的封面图文件路径,若为空,则使用 moear-api-common 中提供的默认图片
img_masthead
当前文章的报头图文件路径,若为空,则使用 moear-api-common 中提供的默认图片
image_filter

图片链接过滤器,用以将无法被前方设置的 package_module 打包工具本地化处理的图片过滤掉,避免影响本地化业务执行效率。

如:当前知乎日报中就会存在公式图片,这些图片是前端生成的,而非静态文件,故会下载异常, 通过过滤器将其滤掉。

内容为 JSON 格式的列表,支持正则表达式

css_package
文章的样式文件路径,这就很关键了(雾),最终打包出来的书籍中排版是否精美全靠它! 此处建议直接根据文章源前端中的样式设计进行移植,剔除掉 kindle 不支持的样式。

文章爬取

此处我是基于 Scrapy 做的爬虫实现,您可以选择自己熟悉的框架,不限制于此。 只要保证 ZhihuDaily.crawl() 的调用为阻塞的,并且返回规定的数据结构&内容即可。

提示

该方法会在 Celery 的单独进程中被调用

注解

此处为便于自动格式化换行,采用的 JSON 格式作为展示,实际返回值为 dict

以下为返回值用例,仅供参考:

[{
    "meta": {
        "spider.zhihu_daily.id": "9677626",
        "moear.cover_image_slug": "https://pic4.zhimg.com/v2-b04b6a5661d4a49cbbe9ff96a245c897.jpg"
    },
    "author": "霍华德,Higerra",
    "title": "为什么欧洲没有苹果、谷歌、阿里这种体量的互联网巨头?",
    "origin_url": "http://daily.zhihu.com/story/9677626",
    "spider": "zhihu_daily",
    "date": "2018-04-09 00:04:00",
    "content": "<div class=\"main-wrap content-wrap\">\n<div class=\"headline\">\n<div class=\"img-place-holder\"></div>\n</div>\n<div class=\"content-inner\">\n<div class=\"question\">\n<h2 class=\"question-title\"></h2>\n<div class=\"answer\">\n<div class=\"meta\">\n<img class=\"avatar\" src=\"http://pic1.zhimg.com/da8e974dc_is.jpg\"/>\n<span class=\"author\">Higerra,</span><span class=\"bio\">圣路易斯华盛顿大学,计算机在读博士,计算机视觉,人工智能</span>\n</div>\n<div class=\"content\">\n<p>对于这个问题,我建议有条件的同学参考一下 Youtube 科技博主 TechAltar 的视频:</p>\n<p><a href=\"https://www.youtube.com/watch?v=zSU5MFPn6Zk\">https://www.youtube.com/watch?v=zSU5MFPn6Zk</a></p>\n<p>这位小哥本人是欧洲人,并且在深圳工作过一段时间,对这个问题应该是很有发言权的。</p>\n<p>首先结论是:欧洲在互联网时代确实落后了(tech deficit)。不只是互联网领域,在新兴的消费电子(手机,电脑,智能设备,电视等)领域欧洲基本已经出局。作者将互联网分为三个层面:基础设施(infrustructure),平台(platform)以及末端应用(application)。欧洲在末端应用方面有不少非常优秀的公司,但是在前两个层面几乎没有存在。美国在前两个层面具有绝对的统治权,少量的挑战几乎均来自中国。</p>\n<p>对于这个现象,作者列出了以下几个原因:</p>\n<ol><li>法规(Regulation):欧洲税负普遍偏高,并且拥有严格的劳工保护法。这些都会对企业发展造成影响。此外欧洲拥有最严格的隐私保护法规,这对于 Google, Facebook, Baidu 之类的主要通过收集用户数据赚钱的公司来说无疑是致命的。</li>\n<li>投资环境(Investment climate):欧洲的初创公司更难获得融资。作者在这点上没有细说,我猜测可能是由于欧洲人偏保守,对于互联网这种虚拟经济比较戒备。</li>\n<li>地理及人口因素(Geography &amp; demographics):欧洲缺乏美国和中国这样巨大的统一市场,这对极其重视用户量的互联网产业是非常不利的。</li>\n<li>对于科技的态度(Attitude):欧洲人对新技术有一种与生俱来的恐惧与不信任感。题外话,前段时间李彦宏说“中国消费者愿意用隐私换取效率”,虽然被喷死了,但其实是事实。和欧洲人相比,中国和美国的消费者更乐于接受新技术。</li>\n<li>创业生态(Startup ecosystem):欧洲缺乏像硅谷以及深圳这样的创新摇篮。</li>\n</ol><p>此外作者还指出,由于欧洲缺乏科技巨头,大部分欧洲本土科技企业最终难逃被美国、中国企业收购的命运。</p>\n<hr/><p>下面是我自己的一些观点。我觉得根本原因在于:</p>\n<ol><li>巨大的单一市场以及庞大的中产阶级。</li>\n<li>良好的基础设施。</li>\n<li>良好的教育水平及科研水平。中国互联网产业的发展很大程度上得益于大量高素质,勤劳以及被勤劳(逃)的码农和研究人员。</li>\n</ol><p>说回欧洲。虽然欧洲的科技企业没有跟上时代的步伐,但是欧洲在传统工业领域依然具有极其强大的实力,并且社会福利非常高。只能说欧洲和中美的发展思维不一样,并不能说谁好谁坏。</p>\n</div>\n</div>\n<div class=\"answer\">\n<div class=\"meta\">\n<img class=\"avatar\" src=\"http://pic3.zhimg.com/9478b8318b2d6cbc774144483b4ac13e_is.jpg\"/>\n<span class=\"author\">霍华德,</span><span class=\"bio\">鹅宝/自然语言处理</span>\n</div>\n<div class=\"content\">\n<p>1. 欧洲有科技巨头</p>\n<p>工业科技巨头西门子了解一下?商用大飞机制造商空客了解一下?奔驰宝马大众了解一下?全球最屌的航空发动机制造商罗罗了解一下?西方有人家数百年的科技积累。</p>\n<p>2. 欧洲的确后劲不足</p>\n<p>就像日本的科技就像突然停滞在上世纪 90 年代之前一样(90 年代之前诞生的科技日本都非常屌),欧洲的科技慢慢也掉队了。</p>\n<p>没有 FLAG,也没有 BAT。人工智能时代,不少大师都曾经是欧洲人(hinton 是英国人,lecun 是法国人),但如今都北美工作,为 FLAG 效力。</p>\n<p>究其原因有很多,但我觉得最关键的还是人口老龄化,出生率下降及欧洲的穆斯林化。科技快速发展是需要聪明的年轻人的,中国如今虽然缺少大师,但聪明的年轻人够多,可以快速吸收欧美 AI 智能领域的先进成果,所以也搞的风生水起。</p>\n<p>-</p>\n<p>不抬杠,缺少巨头就是落后了。没有谷歌就代表欧洲缺乏世界级的信息检索系统,进而导致在大数据领域的落后;没有 Facebook 就代表欧洲缺乏世界级的社交网络,进而导致社会计算能力领域的落后;没有阿里巴巴,就代表欧洲没有处理千亿级日交易额的世界级并发架构,进而导致在顶级架构设计领域的落后。</p>\n<p>全世界具有服务十亿级人口互联网技术的国家就两个,中国服务十四亿用户,美国服务剩下五十亿。欧洲总共十亿人都没有,可能做出服务十亿人的技术吗?中国做出来了,中国要自信,中国就是牛。</p>\n</div>\n</div>\n<div class=\"view-more\"><a href=\"http://www.zhihu.com/question/271381019\">查看知乎讨论<span class=\"js-question-holder\"></span></a></div>\n</div>\n</div>\n</div>"
}, {
    "meta": {
        "spider.zhihu_daily.id": "9677641",
        "moear.cover_image_slug": "https://pic3.zhimg.com/v2-317eac89a5ce40a6b2b07705eaef82f2.jpg",
        "spider.zhihu_daily.top": "1"
    },
    "author": "dhchen",
    "title": "如何阅读一本厚书?",
    "origin_url": "http://daily.zhihu.com/story/9677641",
    "spider": "zhihu_daily",
    "date": "2018-04-09 00:03:00",
    "content": "<div class=\"main-wrap content-wrap\">\n<div class=\"headline\">\n<div class=\"img-place-holder\"></div>\n</div>\n<div class=\"content-inner\">\n<div class=\"question\">\n<h2 class=\"question-title\"></h2>\n<div class=\"answer\">\n<div class=\"meta\">\n<img class=\"avatar\" src=\"http://pic2.zhimg.com/v2-d4f49c9f241ccfa5265c4c9716010425_is.jpg\"/>\n<span class=\"author\">dhchen,</span><span class=\"bio\">Ph.D. in Mathematics</span>\n</div>\n<div class=\"content\">\n<p>首先,你得分清楚你的“厚书”是什么性质的书。比如,你提到的《高等代数》(丘维声)这种是教科书,但是《数学分析典型问题与方法》是一本教辅类(习题类)书,这两类书使用方法的逻辑是不一样的。</p>\n<p>对于一本很厚的教科书,我的建议是:你先读一本薄的。</p>\n<p>别笑,让我们慢慢道来。教科书本质上是在说明一个科目的书。对于此类书,我的做法从来都是“主题阅读法”,<strong>这种读法的目的不在于掌握一本具体的书,而是把握一个科目本身,具体的一两本书只是工具</strong>。比如你读《高等代数》(丘维声)根本的原因是你在学“高等代数”这门课,这本书是这个课的参考资料。找出这个科目的“相关教材”:有长有短,甚至讲义都可以。然后先看一本简单的,然后每学习一个板块,比如行列式,然后就看不同的教材讲行列式是怎么讲,然后自己在脑海里形成一个知识网络,并且通过笔记的方式记录下来。然后进入下一个板块,类似的,也是先看简短的书,再看“复杂”的书。</p>\n<p>有人说这样不是读得更多吗?这样不会更慢吗?</p>\n<p>这方法不会真的拖慢你的速度,这比你死磕一本又厚又难要好得多。让你记住一个随机的 7 个词语你很难记住,但是给你记忆一个包含这 7 个词语的故事更加容易。</p>\n<p>为什么?因为后者更体系化。所谓的厚书本质上是“简略”教材的延伸加强版。一个简略的教材或者教程也是“五脏俱全”的,它们也会涉及到一个科目的重要知识点,问题在于它们缺乏<strong>“细节”和“延伸”。</strong>同样讲行列式,有些教材就是很简单地讲具体的行列式,有一些会通过公理化的方式去建立行列式。<strong>如果你脑内有这个框架,那么你读书的时候就明白为什么这本书要讲这么细,为什么要举这个例子。</strong>不会你读一本厚书的时候不会产生厌烦情绪,也不会觉得困难,速度会非常快。</p>\n<p><strong>你明白这一点就知道如何读一本厚的教材了:</strong>你首先通过一些小册在脑内建立一个大致的体系,一般理科教材是很难通过看前言建立这样的体系。然后你在这个体系内不断填充细节,这样可以比较有效率。这样,你读一本厚书不需要都从头读到尾,你只需要抱着“补充细节”的方式去读就好。这样你的效率会很快。<strong>最重要的是这个方式这个读书方法让你学得深入。</strong></p>\n<p>《数学分析典型问题与方法》这类教辅书本质上没有真正的体系,是很零散的点,你根据需求去参考就好:比如,那种看一眼就会知道怎么做的题目就别去做了,大学很少需要做题的效率。不会做的题目先花上半小时去想,然后再看答案。如果你有考试需求,我甚至建议你要做一个小本子。<strong>我非常反对看见不会做的题目就马上看答案,这样你第二天就忘了怎么做,本质上是因为你压根没学会。</strong>这类书唯一的效率就是少做那些已经“掌握”的东西。</p>\n<p>当然了,前提是你脑海内有一个学科体系。<strong>千万别没读懂书就跑过来做题,这是万万不可的。</strong>那不叫效率,那就作死<strong>。</strong>对于教辅书<strong>,</strong>我实在不觉得有从头“读”到位的必要,这类书不是拿来读的,是拿来用的。<strong>你知道什么东西在什么位置就好</strong>。</p>\n<p><strong>什么叫效率?你学到了才能谈效率。你如果没达到“学到了”这个标准,你没资格谈什么效率。</strong>比如你要学 abcde,你花了 10 个月学完了。一个人花 5 个月也学完了 abcde,他比你有效率,但是另一个人花一个月学了 a,号称自己学完了 abcde,这个人没资格和你谈效率,他得学到 e 才能和你谈效率。</p>\n<p>想法设法在一个月内学到 a,然后号称自己学完 abcde 的人不叫效率,那叫偷懒<strong>。</strong></p>\n</div>\n</div>\n<div class=\"view-more\"><a href=\"http://www.zhihu.com/question/271233511\">查看知乎讨论<span class=\"js-question-holder\"></span></a></div>\n</div>\n</div>\n</div>"
}, {
    "meta": {
        "spider.zhihu_daily.id": "9677554",
        "moear.cover_image_slug": "https://pic1.zhimg.com/v2-67088b10dbe889fdfa64f7fd06b90b84.jpg"
    },
    "author": "李沐",
    "title": "我去美国读博这五年",
    "origin_url": "http://daily.zhihu.com/story/9677554",
    "spider": "zhihu_daily",
    "date": "2018-04-09 00:02:00",
    "content": "<div class=\"main-wrap content-wrap\">\n<div class=\"headline\">\n<div class=\"img-place-holder\"></div>\n</div>\n<div class=\"content-inner\">\n<div class=\"question\">\n<h2 class=\"question-title\">博士这五年</h2>\n<div class=\"answer\">\n<div class=\"meta\">\n<img class=\"avatar\" src=\"http://pic1.zhimg.com/v2-64c0ab337a1bc85f7cbd0aa5949bacd0_is.jpg\"/>\n<span class=\"author\">李沐</span>\n</div>\n<div class=\"content\">\n<p><strong>前言</strong></p>\n<p>12 年 8 月提着一个行李箱降落在匹兹堡机场。没找住的地方,也不知道 CMU 应该怎么去。对未来一片迷茫,但充满乐观。 现在,刚完成了博士期间最后的一场报告,在同样的机场,不过是在等待离开的航班。</p>\n<p>回想过去的五年,是折腾的五年,也是自我感悟和提升的五年。这里我尝试记录这五年主要做过的事情和其中的感想,希望对大家有所启发。</p>\n<p><strong>第 0 年:3/11-8/12</strong></p>\n<p>我第一次申请美国的博士是在 11 年,但拿到的 offer 并没有特别合适的导师,于是就北上投奔文渊去了。 我当时在百度商务搜索部门做广告的点击预估。具体是使用机器学习来预测一个广告是不是会被用户点击。 这时候离“大数据”这个词流行还有两年,但百度那时候的数据即使现在来看仍然是大的。我的任务是如何高效的利用数百台机器快速的在数十 T 的数据上训练出模型。</p>\n<p>当时产品用的算法基于 LBFGS,我于是想是不是可以换个收敛更快的算法。没几天就找到个不错 。但实现上发现了各种问题,包括性能,收敛,和稳定性。而且那时有的就是一个裸的 Linux 和很老版本的 GCC,什么都是需要从头开始写。花了大量时间做系统优化,算法改动,和线上实验,最后一年后在整个广告流量上上了线。</p>\n<p>现在再回顾会觉得整个一年时间都在打磨各种细节上,有时候为了 5%的性能提升花上上千行代码。这些都导致算法过于复杂,有过度设计之嫌。但深入各个细节对个人能力提升很大,而且很多遇到的问题成为了之后研究方向的来源。一些算法上的思考曾写在<a class=\" wrap external\" href=\"http://link.zhihu.com/?target=http%3A//mli.github.io/2013/03/24/the-end-of-feature-engineering-and-linear-model/\" rel=\"nofollow noreferrer\" target=\"_blank\">这里</a>,当时候深度学习刚刚出来,冥冥中觉得这个应该是大规模机器学习的未来,不过真正开始跟进是好几年以后了。</p>\n<p>11 年 12 月中的时候突然心血来潮随手把材料重新寄了一遍,就选了 CMU 和 MIT,结果意外收到了 CMU 的 offer。有天在百度食堂同凯哥(余凯)和潼哥(张潼)吃饭,我说收了 CMU offer,在纠结去不去。他们立马说去跟 Alex Smola 啊,他要要加入 CMU 了,我们给你引荐下。</p>\n<p>记得是离开的前一天才开始打包行李,早上去公司开完会,中午离职,跟小伙伴打招呼说出个国,然后就奔机场了。那天北京天气特别好,完全不记得前一天雾霾刚爆了表。</p>\n<p><strong>第一年:9/12-8/13</strong></p>\n<p>第一年的主要事情是熟悉环境和上课。CMU 课程比较重,博士需要学 8 门课,每门课工作量巨大。而且要求做两门课助教,做助教比上课更累。</p>\n<p>这一年上的课中对我最有用的是“高级分布式系统”。之前在上交 ACM 班的时候已经学过很多质量都还不错课,纯知识性的课程一般对我帮助不大。但这门课主要是读论文,然后大家讨论。不仅仅是关于知识,很多是对设计理念的领悟。大家知道对于系统而言,设计是一门艺术而不是科学,这是设计者审美和哲学理念的体现。同时系统界历史也是由一波又一波的潮流组成,了解历史的发展以及其中不断重复的规律非常有意义。</p>\n<p>那年这门课上课老师是 Hui Zhang(神人之一,20 多岁就在 CMU 任教了,学生包括了 Ion Stoica,他是 Spark 作者 Matei 的导师),他有非常好的大局观,对于“Why”这个问题阐述非常到位。我是通过这门课才对分布式系统有了比较清晰的认识。两年之后我偶然发现我的一篇论文也在这门课的阅读列表里了,算是小成就达成 。</p>\n<p>除了上课,更重要是做研究。我去 CMU 的时候 Alex 那时还在 Google,而且没经费,所以把我丢给了 Dave Andersen。于是我有了两个导师,一个做机器学习,一个做分布式系统。</p>\n<p>前面半年都是在相互熟悉的过程。我们每周会一起聊一个小时。前半年因为 Alex 不在,所以我们只能视频。Alex 那边信号经常不好,而且他有德国和澳大利亚口音,外加思维跳跃,经常我听不懂他说啥只能卖萌傻笑。还是靠着 Dave 不断的打字告诉我 Alex 说了什么才度过了前几次的会。</p>\n<p>两个导师风格迥异。Alex 是属于反应特别快,通常你说一点,他已经想好了接下来十点,要跟上他节奏很难。一般抛出问题的时候他就想好了好几个解决方法。这时候要证明自己的想法比他的更好不容易,需要大量的沟通和实验数据支撑。我想我大概是花了两年证明了在某些方向上我的方案一般更好,所以这时候他就不那么 hands-on 了。</p>\n<p>Dave 不会给很多想法,但会帮助把一个东西理解透,然后讲得很清楚。因为我研究方向主要是机器学习上,基本上前两年基本都是我在教 Dave 什么叫机器学习,而且是尽量不用公式那种教法。</p>\n<p>我的第一个研究工作是关于如果划分数据和计算使得减少机器学习求解中的网络通讯量。Alex 体现了他的强项,几分钟就把问题归纳成了一个优化问题,然后我们三各自提出一个解法。我做了做实验发现 Dave 的算法更好。接下来两个月把算法做了很多优化,然后又做了点理论分析就把论文写了。</p>\n<p>可惜这个想法似乎有点超前,虽然我们一遍又一遍的改进写作,但投了好几个会审稿人就是不理解,或者觉得这个问题不重要。那个时候学术界已经开始吹嘘“大数据”,但我觉得其实大部分人是不懂的,或者他们的“大数据”仍然是几个 GB 的规模,烤 U 盘需要十来分钟的那种。</p>\n<p>这是我在 CMU 的一个工作,我觉得挺有用,但却是唯一没能发表的。</p>\n<p>当时跟我坐同一个办公室的是 Richard Peng,他做的是理论研究。我经常跟他讨论问题,然后有了些想法合作了一个工作。大体思想是把图压缩的快速算法做到矩阵的低秩近似上。这个工作写了三十页公式但没有任何实验,我主要当做写代码间隙的悠闲娱乐,不过运气很好的中了 FOCS。</p>\n<p>坦白说我不是特别喜欢纯理论这种,例如在 bound 的证明中很多大量的项直接丢掉了,导致我觉得 bound 特别的近似。对于做系统的人来说,最后拼的是常数。这个工作中这种大开大合的做法我觉得很不踏实。所以我觉得以后还是应该做更实在点的东西。</p>\n<p>在 CMU 回到了去百度前的一周七天工作无休的节奏。每周至少 80 个小时花在学校。如果累了就去健身房,我一般晚上 12 点去。不仅是我一个人,大家都很努力,例如凌晨的健身房,早 3 点的办公室,四处都可以见到中国或者印度学生。我那时候的室友田渊栋花在学校的时候比我多很多。</p>\n<p>那一阵子有读了很多关于优化的文章。其中对我启发最大的是 Bertsekas 写于 80 年代末的那本关于分布式计算的书。此书可以认为是 MIT 控制领域黄金一代研究成果总结,换到现在仍然不过时。</p>\n<p>受启发我转去研究异步算法,就是分布式下不保证数据的及时性来提升系统性能。我基于在百度期间做的算法,做了一些改进和理论分析,然后投了 NIPS。</p>\n<p>投完 NIPS 就动身去了 Google Research 实习。那时候 Google Brain 成立不久,在“宇宙的答案”42 楼,包括 Jeff Dean,Geoffrey Hinton,Prabhakar Raghavan 好些大牛挤在一起,加起来论文引用率能超 80 万。</p>\n<p>Alex 跟我说,你去读读 Jure Leskovec 的文章,学学人家怎么讲故事。我在 Google 也尝试用了些用户 GPS 数据来对用户行为建模。可是写文章的时候怎么也写不出 Jure 的那种故事感,发现自己不是那块料。这篇文章因为用了用户数据,恰逢 Snowden 让大家意识到隐私的重要性,历经艰辛删了一半结果 Google 才允许发出来。有些累觉不爱。</p>\n<p>不过在 Google 期间我主要时间花在研究内部代码和文档上。Google 的基础架构很好,文档也很健全。虽然没有直接学到了什么,但至少是开了眼界。</p>\n<p><strong>第二年:9/13-8/14</strong></p>\n<p>这学期上了 Tuomas Sandholm 的机制设计,此乃另一大神,例如最近德州扑克赢了专业选手,之前开公司也卖了上亿。不过这门课我是完完全全没学懂,连承诺的课程大作业都没怎么做出来。之后的两年里我一遇到 Tuomas 他都会问下有什么进展没。我只能远远看见他就绕开。</p>\n<p>NIPS 被拒了,发现审稿人不懂线程和进程的区别,有点沮丧。隔壁实验室一篇想法类似但简单很多的论文倒是中了 oral,所以那阵子压力很大。Alex 安慰说这种事情常有发生,看淡点,然后举了很多自己的例子。</p>\n<p>之后想了想,一篇好文章自然需要有足够多的“干货”,或者说信息量, 但一篇能被接受的文章需要满足下面这个公式:</p>\n<blockquote>文章的信息量 / 文章的易读性 &lt; 审稿人水平 * 审稿人花的时间</blockquote>\n<p>对于机器学习会议,因为投稿量大,所以审稿人很多自然平均水平就会下降。而且很多审稿人就花半个小时到一个小时来读文章,所以公式右边数值通常是很小,而且不是我们能控制。</p>\n<p>如果文章的信息量不大,例如是改进前面工作或者一些简单的新想法,那么公式成立的概率很大。而对于信息量大的文章,就需要努力提升易读性,包括清晰的问题设定,足够的上下文解释等等。而前面投的那篇 NIPS,以及更早的那个被拒工作,就是因为我们假设了审稿人有足够多的相关专业知识,而我们塞进了太多干货使得大家都读糊涂了。</p>\n<p>即使对于已经发表的文章,上面那个公式同样可以用来衡量一篇论文的引用率。例如经常见到干货很多的文章没有什么人引用,而同时期的某些工作就是考虑了其中简单特殊情况结果被大引特引。</p>\n<p>接下来的半年我主要在做一个通用的分布式机器学习框架,是想以后做实验方便些。名字就叫 parameter server,沿用了 Alex 10 年论文提出的名字。花了很多时间在接口设计上,做了好几个版本实现,也跑了些工业界级别的大规模的实验。</p>\n<p>不过真正花了我大量时间的是在写论文上。目标是把这个工作投到 OSDI 上,OSDI 是系统界两大会之一。我们预计审稿人跟 Dave 两年前状态差不多,不会有太多机器学习和数学背景,所以需要尽量的少用公式。整整一个月就花在写论文上,14 页的文章满满都是文字和示意图。不过努力没有白费,最终论文被接受了。随后又花了好几周准备大会报告上。相对于平时花一周写论文,两三天准备报告,这次在写作和报告水平上有了很大的提升。没有放进去的公式和定理投了接下来的 NIPS,这次运气很好的中了。</p>\n<p>有了文章后稍微心安了点可以更自由的做些事情。</p>\n<p>寒假回了趟国,跑去百度找了凯哥和潼哥。潼哥说他最近有个想法,于是快糙猛的把实验做了然后写了篇论文投了 KDD。同时期 Alex 一个学生也把他一个一直想让我做但我觉得这个小 trick 不值得我花时间的想法投了 KDD,结果中了最佳论文。作报告那天我在的会场稀稀疏疏几个人,他们隔壁会场人山人海。这个使得好长一段时间我都在琢磨是不是还是要跟着导师走比较好。</p>\n<p>那时凯哥在百度搞少帅计划,觉得蛮合适就加入了。这时凯哥正带着一大帮兄弟轰轰烈烈的搞深度学习,我自然也是跳坑了。试过好几个想法后,我觉得做做分布式的深度学习框架比较对胃口。我挑了 CXXNet 作为起点,主要是因为跟天奇比较熟。同时也慢慢上手跑一些 Alexnet 之类的实验。</p>\n<p>我是因为少帅计划才开始开始做深度学习相关项目,凯哥也很支持我做开源开发回馈社会而不是只做公司内部的产品。但在少帅期间并没有做出什么对公司有帮助的事,很是惭愧。</p>\n<p><strong>第三年:9/14-8/15</strong></p>\n<p>回 CMU 后 Alex 看见深度学习这么火,说我们也去买点 GPU 玩玩。但我们比较穷,只能去 newegg 上掏点便宜货。这个开启了轰轰烈烈的机器折腾之旅。整个一年我觉得我都在买买买装装装上。最终我们可能就花了小几万刀攒出了一个有 80 块 GPU 的集群。现在想想时间上花费不值得,而且为了图便宜买了各种型号的硬件导致维护成本高。但当时候乐在其中。具体细节可以看这篇 <a class=\" wrap external\" href=\"http://link.zhihu.com/?target=http%3A//mli.github.io/gpu/2016/01/17/build-gpu-clusters/\" rel=\"nofollow noreferrer\" target=\"_blank\">blog</a></p>\n<p>这一年写了很多 parameter server 代码,同时花了很时间帮助用户使用这些代码。很难说做得很成功,现在想想有几个原因。写代码时我会优先考虑性能和支持最多的机器学习算法。但正如前面的错误,忽略了代码的易读性,从而导致只有少部分人能理解代码从而做一些开发。例如我尝试让 Alex 组的学生来使用这些代码,但其中的各种异步和 callback 让他们觉得很是难懂。其次是没有人能一起审核代码接口,导致这些接口有浓浓的个人味道,很难做到对所有人都简单明了。</p>\n<p>不过幸运的是找到一帮志同道合的小伙伴。最早是我发现天奇在写 xgboost 的分布式启动脚本,我看了看发现挺好用,就跟他聊了聊。聊下的发现有很多基础部件例如启动脚本,文件读取应该是可以多个项目共同使用,而不是每个项目都造一个轮子。于是跟天奇在 Github 上创建了一个叫 DMLC 的组织,用来加强合作和沟通。第一个项目是 dmlc-core,放置了启动和数据读取代码。</p>\n<p>DMLC 的第二个新项目叫 wormhole。想法是提供一系列分布式机器学习算法,他们使用差不多相同的配置参数来统一用户体验。我把 parameter server 里面的机器学习相关算法移植了过来,天奇移植了 xgboost。Parameter server 原有的系统代码简化到了 ps-lite。</p>\n<p>中途我听百度同学说 factorization machine(FM)在广告数据上效果不错,所以在 wormhole 上实现了下。针对分布式做了一些优化,然后投了 WSDM。前后没有花到一个月,但神奇的竟然拿了最佳论文提名。</p>\n<p>在 wormhole 的开发中发现一个问题,就是各个算法还是挺不一样,他们可以共用一些代码,但又有各自的特点,需要特别的优化来保证性能。这样导致维护有些困难,例如对共用代码的改动导致所有项目都要检查下。总结下来觉得一个项目最好只做一件事情。所以天奇把 xgboost 代码放回原来项目,我也把 FM 独立出来一个项目叫 difacto。</p>\n<p>通过一系列的项目,我学到的一点是,以目前的水平和人力,做一个通用而且高效的分布式机器学习框架是很难的一件事情。比较可行的是针对一类相似的机器学习算法做针对性的项目。这个项目的接口必须是符合这类算法结构,所以做算法开发的同学也能容易理解,而不是过多暴露底层系统细节。</p>\n<p>真正的让 DMLC 社区壮大的项目是第三个,叫做 MXNet。当时的背景是 CXXNet 达到了一定的成熟度,但它的灵活性有局限性。用户只能通过一个配置项来定义模型,而不是交互式的编程。另外一个项目是 zz 和敏捷他们做的 Minerva,是一个类似 numpy 的交互式编程接口,但这个灵活的接口对稳定性和性能优化带来很多挑战。我当时候同时给两个项目做分布式的扩展,所有都有一定的了解。然后一个自然的想法是,把两个项目合并起来取长补短岂不是很好。</p>\n<p>召集了两个项目的开发人员讨论了几次,有了大致的眉目。新项目取名 MXNet,可以叫做 mixed-net,是前面两个名字(Minerva 和 CXXNet)的组合。放弃开发了几年的项目不是容易的决定,但幸运的是小伙伴都愿意最求更好,所以 MXNet 进展挺顺利。很快就有了可以跑的第一个版本。</p>\n<p><strong>第四年:9/15-8/16</strong></p>\n<p>前半年为 difacto 和 MXNet 写了很多代码。其实一开始的时候我觉得 difacto 更重要些,毕竟它对于线性算法的提升非常显著而且额外的计算开销并不大,这对广告预估之类的应用会有非常大的提升。但有次遇到 Andrew Ng,我跟他说我同时在做这两个项目,他立即告诉我我应该全部精力放在 MXNet 上,这个的未来空间会大很多。我一直很佩服 Andrew 的眼光,所以听了他的建议。</p>\n<p>11 月的时候 MXNet 就有了很高的完成度。写了个小论文投去了 NIPS 的 workshop 也算是歇了口气。但随后就听到了 TensorFlow(TF)开源的消息。由 Jeff Dean 领导大量全职工程师开发,Google 庞大的宣传机器支持,不出意料迅速成为最流行的深度学习平台。TF 对我们压力还是蛮大,我们有核心开发者转去用了 TF。不过 TF 的存在让我领悟到一点,与其过分关心和担忧对手,不如把精力集中在把自己的做得更好。</p>\n<p>NIPS 的时候 MXNet 的小伙伴聚了一次,有好几个我其实是第一次见面。随后 Nvidia 的 GTC 邀请我们去做报告。在这两次之间大家爆发了一把,做了很多地方的改进。同时用户也在稳步增长。我们一直觉得 MXNet 是小开发团队所以做新东西快这是一个优势,但随着用户增加,收到抱怨说开发太快导致很多模块兼容性有问题。有段时间也在反思要在新技术开发速度和稳定性之间做一些权衡。</p>\n<p>这时一夜之间大数据不再流行,大家都在谈深度学习了。</p>\n<p>我也花了很多力气在宣传 MXNet 和争取开发者上。包括微博知乎上吼一吼,四处给报告。在大量的点赞声中有些陶醉,但很多中肯的批评也让我意识到重要的一点,就是应该真诚的分享而不是简单的吹嘘。</p>\n<p>因为大量的媒体介入,整个深度学习有娱乐化的趋势。娱乐化的报道很多都只是一些简单信息,(有偏见)的观点,而没有太多干货。不仅对别人没营养,对自己来说也就是满足虚荣心。与其写这些简单的水文,不如静下心做一些有深度的分享,包括技术细节,设计思路,和其中的体会。</p>\n<p>此类分享一个容易陷入的误区是只关注自己做了什么,结果多么好。这些确实能证明个人能力,对于想重复这个工作的人来说会有很大帮助。但更多的人更关心的是适用范围在哪里,就是什么情况下效果会减弱;为什么结果会那么好;insight 是什么。这个需要更多深入的理解和思考,而不是简单的展示结果。</p>\n<p>这个对写论文也是如此。只说自己的结果比基线好多少只能说明这是不错的工作,但结果再好并不能意味这个工作有深度。</p>\n<p>深度学习的火热导致了各种巨资收购初创司不断。Alex 也有点按耐不住, 结果是他,Dave,Ash(曾经是 YahooCTO)和我合伙弄了一家公司,拿了几十万的天使投资就开工了。Alex 写爬虫,Dave 写框架,我跑模型,风风火火干了好一阵子。可惜中途 Dave 跑路去跟 Jeff 做 TF 了。后来这个公司卖给了一个小上市公司。再后来我们觉得这个公司不靠谱也就没考虑跟他们干了。</p>\n<p>第一次创业不能说很成功,从中学到几点:一是跟教授开公司一定要注意有太多想法但没死死的掐住一个做,二是找一堆兼职的博士生来干活不是特别靠谱,尤其是产品不明确的时候,三是即使要卖公司也一定要做一个产品出来。我们卖的时候给很多人的感觉是团队人太强但产品太弱,所以他们只想要人而已。四是试图想要通过技术去改变一个非技术公司是很难的事情,尤其是过于新的技术。</p>\n<p>然后我们就奔去折腾下一个公司。Ash 早财务自由所以想做一个大的想法,但这时 Alex 刚在湾区买了个房,有还贷压力,他选择去了 Amazon。于是算是胎死腹中。</p>\n<p>随后收到 Jeff 的邮件说有没有兴趣加入 Google,自然这是一个很诱人的机会。同时我觉得小的创业技术性强的公司是不错的选择。但从 MXNet 的发展上来书,去 Amazon 是最好选择之一。自己挖的坑,总是要自己填的。所以我以兼职的身份去了 Amazon,领着一帮小弟做些 MXNet 开发和 AWS 上深度学习的应用。</p>\n<p><strong>第五年:9/16-2/17</strong></p>\n<p>早在 15 年初 Alex 就表示我可以毕业了,但作为拖延晚期患者,迟迟没开始准备。这时候感觉不能再拖了,于是窝在湾区写毕业论文。Alex 觉得毕业论文应该好好写,但我对把前面都做完的东西再捣鼓写写实在是没兴趣,尤其是加州太阳那么好,大部分时间我都是躺在后院晒太阳。此时 B 站已经完全被小学生占领,这边买书也不方便,无聊之余刷了很多起点。然后还写了篇<a class=\"internal\" href=\"https://zhuanlan.zhihu.com/p/23781756\">炼丹文</a>。</p>\n<p>CMU 要求答辩委员会需要有三个 CMU 老师和一个学校外的。除了两个导师外,我找了 Jeff Dean 和刚加入 CMU 的 Ruslan Salakhutdinov. 结果 Russ 随后就加入了 Apple,整个委员会的人都在湾区了。Jeff 开玩笑说可以来 Google 答辩。可惜跟 CMU 争吵了好多次,还是不允许在校外答辩,而且必须要三个人委员会成员在场。这些限制导致答辩一拖再拖,而且临时加了 Barnabas Poczos 来凑人数。最后是 Jeff 的助理快刀斩乱麻的协调好了时间把所有东西定好了。没有她估计我还可以拖几个月。</p>\n<p>答辩的时候是一个比较奇异的状态,委员会里有 Google, Amazon, Apple 的 AI 负责人,剩下两个和我又分别在这三家公司兼职。这个反应了当下 AI 领域学术界纷纷跑去工业界的趋势。</p>\n<p>不过答辩这个事情倒是挺简单,跟平常做个报告没什么太多区别。一片祥和,即使 Russ 问了 MXNet 和 TensorFlow 哪家强这个问题也没有打起来。</p>\n<p>答辩后我问委员会说,我在考虑找个学术界的工作,有什么建议没。大家介绍了一大堆经验,不过大家都强调的一个重点是:学术界好忙好忙,而且好穷好穷,工业界的薪水(就差指自己脸了)分分钟秒掉 CMU 校长。你要好好想。</p>\n<p><strong>总结</strong></p>\n<p>答辩前一天的晚上,我想了两个问题,一个是“博士收获最大的是什么”,另一个是“如果可以重来会怎么办”。对于第一个问题,这五年时间自然学到了很多东西,例如系统的学习了分布式系统,紧跟了机器学习这五年的发展,写文章做幻灯片做报告水平有提升,代码能力也加强了些。自信上有所提高,觉得既可以做一流的研究,也可以写跟大团队 PK 的代码。只要努力,对手没什么可怕的。</p>\n<p>但更重要的是博士的五年的时间可以专注的把一些事情从技术上做到最好,做出新的突破,这个氛围没有其他地方能给予。</p>\n<p>第二个问题的一个选项是当年留在国内会怎么样? 当年百度的伙伴们多数现在都做得很好,都在引领这一波 AI 的潮流,甚至有好几个创造了上亿价值的公司。所以从金钱或者影响力角度来看,一直在工业界也不差,说不定现在已经是土豪了。</p>\n<p>不过我觉得还是会选择读博。赚钱以后还有大把时间可以,但是能花几年时间在某个领域从入门到精通甚至到推动这个领域发展的机会就一次。站在这个领域的高点会发现世界虽然很大,但其实其他领域也使用差不多的技术,有着同样的发展规律。博士期间领悟到的学习的方法可以在各个方向上都会大有作为。</p>\n<p>更重要的是理想和情怀。人一生要工作五十年,为什么不花五年来追求下理想和情怀呢?</p>\n<div class=\"view-more\"><a href=\"http://zhuanlan.zhihu.com/p/25099638\">查看知乎讨论</a></div>\n</div>\n</div>\n</div>\n</div>\n</div>"
}, {
    "meta": {
        "spider.zhihu_daily.id": "9677635",
        "moear.cover_image_slug": "https://pic4.zhimg.com/v2-90b133da744defcff96e9efdcd4f39f3.jpg"
    },
    "author": "知乎用户,钟钟,霜霰,蒋占山",
    "title": "瞎扯 · 如何正确地吐槽",
    "origin_url": "http://daily.zhihu.com/story/9677635",
    "spider": "zhihu_daily",
    "date": "2018-04-09 00:01:00",
    "content": "<div class=\"main-wrap content-wrap\">\n<div class=\"headline\">\n<div class=\"img-place-holder\"></div>\n</div>\n<div class=\"content-inner\">\n<div class=\"question\">\n<h2 class=\"question-title\">外星人对地球有哪些会令地球人大吃一惊的刻板印象?</h2>\n<div class=\"answer\">\n<div class=\"meta\">\n<img class=\"avatar\" src=\"http://pic3.zhimg.com/076370fd5013e2b4f6540cb48784970e_is.jpg\"/>\n<span class=\"author\">钟钟,</span><span class=\"bio\">曾因多情鞭美人,生怕酒醉累名马</span>\n</div>\n<div class=\"content\">\n<p>我们决定搬给地球人「最佳花式烧开水奖」。</p>\n<p>评语:在茫茫宇宙之中,智慧种族获取能量的方式千奇百怪,烧开水在某些智慧种族也曾经出现过,但是没有一个象地球人这样热衷于烧开水的。</p>\n<p>我们决定搬这个奖给地球人的理由是:他们通过各种方式获得能源资源,比如木材,煤炭,石油,天然气,太阳能,核裂变,核聚变等,但这些能源资源的使用目的就是烧开水。</p>\n<p>现在有请地球人代表上台领奖!</p>\n<p>有请地球人代表发表获奖感言!</p>\n<p>地球人代表泪流满面:我们他妈的点错科技树了!</p>\n<hr/><p>评论区 @<a class=\"UserLink-link\" href=\"https://www.zhihu.com/people/shen-yi-66-37\" target=\"_blank\">哈撒改</a>:各类发电站其实就是用各种能源把水烧成蒸汽。</p>\n</div>\n</div>\n<div class=\"answer\">\n<div class=\"meta\">\n<img class=\"avatar\" src=\"http://pic2.zhimg.com/v2-c63acf4bfee1ab6ea934db78fa850605_is.jpg\"/>\n<span class=\"author\">霜霰,</span><span class=\"bio\">学生</span>\n</div>\n<div class=\"content\">\n<p>这问题下的多数回答也体现出地球人对外星人的刻板印象。</p>\n</div>\n</div>\n<div class=\"view-more\"><a href=\"http://www.zhihu.com/question/265244158\">查看知乎讨论<span class=\"js-question-holder\"></span></a></div>\n</div>\n<div class=\"question\">\n<h2 class=\"question-title\">你见过哪些「没什么鸟用」的APP?</h2>\n<div class=\"answer\">\n<div class=\"meta\">\n<img class=\"avatar\" src=\"http://pic1.zhimg.com/da8e974dc_is.jpg\"/>\n<span class=\"author\">知乎用户,</span><span class=\"bio\">vox populi, vox dei.</span>\n</div>\n<div class=\"content\">\n<p>你永远不知道 deadline 能把人逼成什么样。</p>\n<p>上学期学了一门安卓开发,课上到三分之一要开始项目提案了。</p>\n<p>那时我们刚学了 sensor,看了一下安卓的 sensor 文档,里面有一项是温度。</p>\n<p>那时我沉迷烘焙,老想烤个蛋糕烤个鸡。但是又葛朗台附体,舍不得买个烤箱温度计。</p>\n<p>于是我用无比严肃的语调和组员做提案。要不然写一个安卓温度烤箱计……</p>\n<p>同学们都用「诶,有点儿意思」的表情看向我。</p>\n<p>我说:「……利用安卓的温度传感,在屏幕上实时显示烤箱温度。用的方法很简单,启动 app 放进烤箱就好了。」</p>\n<p>同学用鼓励的神情让我继续发言。</p>\n<p>「……缺点就是只能用一次,并且要时不时地趴在烤箱前面读数。因为指不定下一秒手机就糊了。当然我们也可以加入语音播报……」</p>\n</div>\n</div>\n<div class=\"view-more\"><a href=\"http://www.zhihu.com/question/269070103\">查看知乎讨论<span class=\"js-question-holder\"></span></a></div>\n</div>\n<div class=\"question\">\n<h2 class=\"question-title\">外国人第一次喝中国白酒是种怎样的体验?</h2>\n<div class=\"answer\">\n<div class=\"meta\">\n<img class=\"avatar\" src=\"http://pic1.zhimg.com/e49a657d4014162887a245d3039e4478_is.jpg\"/>\n<span class=\"author\">蒋占山,</span><span class=\"bio\">非洲扛把子,吴彦祖plus。</span>\n</div>\n<div class=\"content\">\n<p><img alt=\"\" class=\"content-image\" src=\"http://pic3.zhimg.com/70/v2-e4dc6e1ec400233106cf31aea41ff0f6_b.jpg\"/></p>\n<p>我差点把赞比亚矿业部部长,喝进重病监护室,我会乱讲?!</p>\n<p><img alt=\"\" class=\"content-image\" src=\"http://pic4.zhimg.com/70/v2-04d82fcab9f164546274f7c61b4d5e67_b.jpg\"/></p>\n<p>上面的图,是当地干警,来调查具体情况的图片。</p>\n<p>没错,我第二天七点起来上班了。</p>\n<p>没错,这位大胸 dei 误以为我要下毒害他……</p>\n<p> </p>\n<p>为什么我不中途阻止他?</p>\n<p>因为黑人喝酒不上脸啊!!!</p>\n<p>不接受任何反驳。</p>\n<p><img alt=\"\" class=\"content-image\" src=\"http://pic3.zhimg.com/70/v2-497aa873dc6a686ef74bc81f6ae63d0a_b.jpg\"/></p>\n<p>赞比亚捕快带的武器里面,没有子弹的。</p>\n<p>他们是两个人一组,一个人拿武器,带一个空弹夹。</p>\n<p>一人带弹夹,有子弹。</p>\n<p>很唬人的。ლ(╹◡╹ლ)</p>\n</div>\n</div>\n<div class=\"view-more\"><a href=\"http://www.zhihu.com/question/271076738\">查看知乎讨论<span class=\"js-question-holder\"></span></a></div>\n</div>\n</div>\n</div>"
}]
字段说明
spider
爬虫的 name 名称
origin_url
文章的原始链接地址
author
文章作者,存在多名作者时,可使用 进行分割,如: 知乎用户,钟钟,霜霰,蒋占山
date

文章发布时间,格式 Y-m-d H:M:S ,具体见上方用例

额外说明,由于知乎日报中不存在此数据,故我根据文章在列表中的顺序进行了伪造 (因为打包文章时会根据发布时间做降序排列)

title
文章标题,用于生成书籍目录
content
文章内容,即从文章源抓取到的 HTML 内容,包含相应的样式类名,用以和注册时提供的样式文件一同使用
meta

文章元数据,其中保存一些不一定每个文章源都有的不定字段,其中有些是通用的会在 MoEar 层, 或响应的插件中被协同使用,有些是专用的,即仅当前包中使用,此处生成,并在之后的 ZhihuDaily.format() 中被使用消化掉,当前存在的值罗列如下:

moear.cover_image_slug
通用字段,封面图片链接,会在打包时将其本地化,置于每篇文章的封面中显示
spider.zhihu_daily.id
专用字段,知乎日报体系同的文章ID,没卵用,就为了在 DB 中存一下,并没有实际使用
spider.zhihu_daily.top
专用字段,标志为知乎日报中的 热闻 ,用以提供期刊模式 mobi 打包时区分章节使用。 会在 ZhihuDaily.format() 中进行处理

文章格式化

此方法用于在 MoEar 指定打包任务前,将从 DB 中获取的文章列表传入相应 spider 插件的 ZhihuDaily.format() 方法,用以格式化为打包插件支持的数据结构,并返回

提示

该方法会在 Celery 的单独进程中被调用

以下为返回值数据结构用例,仅供参考:

OrderedDict([('热闻', [{
    'content': '<div class="main-wrap content-wrap">\n<div class="headline">\n<div class="img-place-holder"></div>\n</div>\n<div class="content-inner">\n<div class="question">\n<h2 class="question-title"></h2>\n<div class="answer">\n<div class="meta">\n<img class="avatar" src="http://pic2.zhimg.com/v2-d4f49c9f241ccfa5265c4c9716010425_is.jpg"/>\n<span class="author">dhchen,</span><span class="bio">Ph.D. in Mathematics</span>\n</div>\n<div class="content">\n<p>首先,你得分清楚你的“厚书”是什么性质的书。比如,你提到的《高等代数》(丘维声)这种是教科书,但是《数学分析典型问题与方法》是一本教辅类(习题类)书,这两类书使用方法的逻辑是不一样的。</p>\n<p>对于一本很厚的教科书,我的建议是:你先读一本薄的。</p>\n<p>别笑,让我们慢慢道来。教科书本质上是在说明一个科目的书。对于此类书,我的做法从来都是“主题阅读法”,<strong>这种读法的目的不在于掌握一本具体的书,而是把握一个科目本身,具体的一两本书只是工具</strong>。比如你读《高等代数》(丘维声)根本的原因是你在学“高等代数”这门课,这本书是这个课的参考资料。找出这个科目的“相关教材”:有长有短,甚至讲义都可以。然后先看一本简单的,然后每学习一个板块,比如行列式,然后就看不同的教材讲行列式是怎么讲,然后自己在脑海里形成一个知识网络,并且通过笔记的方式记录下来。然后进入下一个板块,类似的,也是先看简短的书,再看“复杂”的书。</p>\n<p>有人说这样不是读得更多吗?这样不会更慢吗?</p>\n<p>这方法不会真的拖慢你的速度,这比你死磕一本又厚又难要好得多。让你记住一个随机的 7 个词语你很难记住,但是给你记忆一个包含这 7 个词语的故事更加容易。</p>\n<p>为什么?因为后者更体系化。所谓的厚书本质上是“简略”教材的延伸加强版。一个简略的教材或者教程也是“五脏俱全”的,它们也会涉及到一个科目的重要知识点,问题在于它们缺乏<strong>“细节”和“延伸”。</strong>同样讲行列式,有些教材就是很简单地讲具体的行列式,有一些会通过公理化的方式去建立行列式。<strong>如果你脑内有这个框架,那么你读书的时候就明白为什么这本书要讲这么细,为什么要举这个例子。</strong>不会你读一本厚书的时候不会产生厌烦情绪,也不会觉得困难,速度会非常快。</p>\n<p><strong>你明白这一点就知道如何读一本厚的教材了:</strong>你首先通过一些小册在脑内建立一个大致的体系,一般理科教材是很难通过看前言建立这样的体系。然后你在这个体系内不断填充细节,这样可以比较有效率。这样,你读一本厚书不需要都从头读到尾,你只需要抱着“补充细节”的方式去读就好。这样你的效率会很快。<strong>最重要的是这个方式这个读书方法让你学得深入。</strong></p>\n<p>《数学分析典型问题与方法》这类教辅书本质上没有真正的体系,是很零散的点,你根据需求去参考就好:比如,那种看一眼就会知道怎么做的题目就别去做了,大学很少需要做题的效率。不会做的题目先花上半小时去想,然后再看答案。如果你有考试需求,我甚至建议你要做一个小本子。<strong>我非常反对看见不会做的题目就马上看答案,这样你第二天就忘了怎么做,本质上是因为你压根没学会。</strong>这类书唯一的效率就是少做那些已经“掌握”的东西。</p>\n<p>当然了,前提是你脑海内有一个学科体系。<strong>千万别没读懂书就跑过来做题,这是万万不可的。</strong>那不叫效率,那就作死<strong>。</strong>对于教辅书<strong>,</strong>我实在不觉得有从头“读”到位的必要,这类书不是拿来读的,是拿来用的。<strong>你知道什么东西在什么位置就好</strong>。</p>\n<p><strong>什么叫效率?你学到了才能谈效率。你如果没达到“学到了”这个标准,你没资格谈什么效率。</strong>比如你要学 abcde,你花了 10 个月学完了。一个人花 5 个月也学完了 abcde,他比你有效率,但是另一个人花一个月学了 a,号称自己学完了 abcde,这个人没资格和你谈效率,他得学到 e 才能和你谈效率。</p>\n<p>想法设法在一个月内学到 a,然后号称自己学完 abcde 的人不叫效率,那叫偷懒<strong>。</strong></p>\n</div>\n</div>\n\n</div>\n</div>\n</div>',
    'meta': {
        'spider.zhihu_daily.id': '9677641',
        'moear.cover_image_slug': 'https://pic3.zhimg.com/v2-317eac89a5ce40a6b2b07705eaef82f2.jpg'
    },
    'author': 'dhchen',
    'excerpt': '\n首先,你得分清楚你的“厚书”是什么性质的书。比如,你提到的《高等代数》(丘维声)这种是教科书,但是《数学分析典型问题与方法》是一本教辅类(习题类)书,这两类书使用方法的逻辑是不一样的。\n对于一本很厚的教科书,我的建议是:你先读一本薄的。\n别笑,让我们慢慢道来。教科书本质上是在说明一个科目的书。对于此类书,我的做法从来都是“主题阅读法”,这种读法的目的不在于掌握一本具体的书,而是把握一个科目本身,具体的一两本书只是工具。比如你读《高等代数》(丘维声)根本的原因是你在学“高等代数”这门课,这本书是这个课的参考资料。找出这个科目的“相关教材”:有长有短,甚至讲义都可以。然后先看一本简单的,然后每学习一个板块,比如行列式,然后就看不同的教材讲行列式是怎么讲,然后自己在脑海里形成一个知识网络,并且通过笔记的方式记录下来。然后进入下一个板块,类似的,也是先看简短的书,再看“复杂”的书。\n有人说这样不是读得更多吗?这样不会更慢吗?\n这方法不会真的拖慢你的速度,这比你死磕一本又厚又难要好得多。让你记住一个随机的 7 个词语你很难记住,但是给你记忆一个包含这 7 个词语的故事更加容易。\n为什么?因为后',
    'origin_url': 'http://daily.zhihu.com/story/9677641',
    'spider': 'zhihu_daily',
    'date': '2018-04-09 00:03:00',
    'title': '如何阅读一本厚书?'
}]), ('日报', [{
    'content': '<div class="main-wrap content-wrap">\n<div class="headline">\n<div class="img-place-holder"></div>\n</div>\n<div class="content-inner">\n<div class="question">\n<h2 class="question-title"></h2>\n<div class="answer">\n<div class="meta">\n<img class="avatar" src="http://pic1.zhimg.com/da8e974dc_is.jpg"/>\n<span class="author">Higerra,</span><span class="bio">圣路易斯华盛顿大学,计算机在读博士,计算机视觉,人工智能</span>\n</div>\n<div class="content">\n<p>对于这个问题,我建议有条件的同学参考一下 Youtube 科技博主 TechAltar 的视频:</p>\n<p><a href="https://www.youtube.com/watch?v=zSU5MFPn6Zk">https://www.youtube.com/watch?v=zSU5MFPn6Zk</a></p>\n<p>这位小哥本人是欧洲人,并且在深圳工作过一段时间,对这个问题应该是很有发言权的。</p>\n<p>首先结论是:欧洲在互联网时代确实落后了(tech deficit)。不只是互联网领域,在新兴的消费电子(手机,电脑,智能设备,电视等)领域欧洲基本已经出局。作者将互联网分为三个层面:基础设施(infrustructure),平台(platform)以及末端应用(application)。欧洲在末端应用方面有不少非常优秀的公司,但是在前两个层面几乎没有存在。美国在前两个层面具有绝对的统治权,少量的挑战几乎均来自中国。</p>\n<p>对于这个现象,作者列出了以下几个原因:</p>\n<ol><li>法规(Regulation):欧洲税负普遍偏高,并且拥有严格的劳工保护法。这些都会对企业发展造成影响。此外欧洲拥有最严格的隐私保护法规,这对于 Google, Facebook, Baidu 之类的主要通过收集用户数据赚钱的公司来说无疑是致命的。</li>\n<li>投资环境(Investment climate):欧洲的初创公司更难获得融资。作者在这点上没有细说,我猜测可能是由于欧洲人偏保守,对于互联网这种虚拟经济比较戒备。</li>\n<li>地理及人口因素(Geography &amp; demographics):欧洲缺乏美国和中国这样巨大的统一市场,这对极其重视用户量的互联网产业是非常不利的。</li>\n<li>对于科技的态度(Attitude):欧洲人对新技术有一种与生俱来的恐惧与不信任感。题外话,前段时间李彦宏说“中国消费者愿意用隐私换取效率”,虽然被喷死了,但其实是事实。和欧洲人相比,中国和美国的消费者更乐于接受新技术。</li>\n<li>创业生态(Startup ecosystem):欧洲缺乏像硅谷以及深圳这样的创新摇篮。</li>\n</ol><p>此外作者还指出,由于欧洲缺乏科技巨头,大部分欧洲本土科技企业最终难逃被美国、中国企业收购的命运。</p>\n<hr/><p>下面是我自己的一些观点。我觉得根本原因在于:</p>\n<ol><li>巨大的单一市场以及庞大的中产阶级。</li>\n<li>良好的基础设施。</li>\n<li>良好的教育水平及科研水平。中国互联网产业的发展很大程度上得益于大量高素质,勤劳以及被勤劳(逃)的码农和研究人员。</li>\n</ol><p>说回欧洲。虽然欧洲的科技企业没有跟上时代的步伐,但是欧洲在传统工业领域依然具有极其强大的实力,并且社会福利非常高。只能说欧洲和中美的发展思维不一样,并不能说谁好谁坏。</p>\n</div>\n</div>\n<div class="answer">\n<div class="meta">\n<img class="avatar" src="http://pic3.zhimg.com/9478b8318b2d6cbc774144483b4ac13e_is.jpg"/>\n<span class="author">霍华德,</span><span class="bio">鹅宝/自然语言处理</span>\n</div>\n<div class="content">\n<p>1. 欧洲有科技巨头</p>\n<p>工业科技巨头西门子了解一下?商用大飞机制造商空客了解一下?奔驰宝马大众了解一下?全球最屌的航空发动机制造商罗罗了解一下?西方有人家数百年的科技积累。</p>\n<p>2. 欧洲的确后劲不足</p>\n<p>就像日本的科技就像突然停滞在上世纪 90 年代之前一样(90 年代之前诞生的科技日本都非常屌),欧洲的科技慢慢也掉队了。</p>\n<p>没有 FLAG,也没有 BAT。人工智能时代,不少大师都曾经是欧洲人(hinton 是英国人,lecun 是法国人),但如今都北美工作,为 FLAG 效力。</p>\n<p>究其原因有很多,但我觉得最关键的还是人口老龄化,出生率下降及欧洲的穆斯林化。科技快速发展是需要聪明的年轻人的,中国如今虽然缺少大师,但聪明的年轻人够多,可以快速吸收欧美 AI 智能领域的先进成果,所以也搞的风生水起。</p>\n<p>-</p>\n<p>不抬杠,缺少巨头就是落后了。没有谷歌就代表欧洲缺乏世界级的信息检索系统,进而导致在大数据领域的落后;没有 Facebook 就代表欧洲缺乏世界级的社交网络,进而导致社会计算能力领域的落后;没有阿里巴巴,就代表欧洲没有处理千亿级日交易额的世界级并发架构,进而导致在顶级架构设计领域的落后。</p>\n<p>全世界具有服务十亿级人口互联网技术的国家就两个,中国服务十四亿用户,美国服务剩下五十亿。欧洲总共十亿人都没有,可能做出服务十亿人的技术吗?中国做出来了,中国要自信,中国就是牛。</p>\n</div>\n</div>\n\n</div>\n</div>\n</div>',
    'meta': {
        'spider.zhihu_daily.id': '9677626',
        'moear.cover_image_slug': 'https://pic4.zhimg.com/v2-b04b6a5661d4a49cbbe9ff96a245c897.jpg'
    },
    'author': '霍华德,Higerra',
    'excerpt': '\n对于这个问题,我建议有条件的同学参考一下 Youtube 科技博主 TechAltar 的视频:\nhttps://www.youtube.com/watch?v=zSU5MFPn6Zk\n这位小哥本人是欧洲人,并且在深圳工作过一段时间,对这个问题应该是很有发言权的。\n首先结论是:欧洲在互联网时代确实落后了(tech deficit)。不只是互联网领域,在新兴的消费电子(手机,电脑,智能设备,电视等)领域欧洲基本已经出局。作者将互联网分为三个层面:基础设施(infrustructure),平台(platform)以及末端应用(application)。欧洲在末端应用方面有不少非常优秀的公司,但是在前两个层面几乎没有存在。美国在前两个层面具有绝对的统治权,少量的挑战几乎均来自中国。\n对于这个现象,作者列出了以下几个原因:\n法规(Regulation):欧洲税负普遍偏高,并且拥有严格的劳工保护法。这些都会对企业发展造成影响。此外欧洲拥有最严格的隐私保护法规,这对于 Google, Facebook, Baidu 之类的主要通过收集用户数据赚钱的公司来说无疑是致命的。\n投资环境(Investm',
    'origin_url': 'http://daily.zhihu.com/story/9677626',
    'spider': 'zhihu_daily',
    'date': '2018-04-09 00:04:00',
    'title': '为什么欧洲没有苹果、谷歌、阿里这种体量的互联网巨头?'
}, {
    'content': '<div class="main-wrap content-wrap">\n<div class="headline">\n<div class="img-place-holder"></div>\n</div>\n<div class="content-inner">\n<div class="question">\n<h2 class="question-title">博士这五年</h2>\n<div class="answer">\n<div class="meta">\n<img class="avatar" src="http://pic1.zhimg.com/v2-64c0ab337a1bc85f7cbd0aa5949bacd0_is.jpg"/>\n<span class="author">李沐</span>\n</div>\n<div class="content">\n<p><strong>前言</strong></p>\n<p>12 年 8 月提着一个行李箱降落在匹兹堡机场。没找住的地方,也不知道 CMU 应该怎么去。对未来一片迷茫,但充满乐观。 现在,刚完成了博士期间最后的一场报告,在同样的机场,不过是在等待离开的航班。</p>\n<p>回想过去的五年,是折腾的五年,也是自我感悟和提升的五年。这里我尝试记录这五年主要做过的事情和其中的感想,希望对大家有所启发。</p>\n<p><strong>第 0 年:3/11-8/12</strong></p>\n<p>我第一次申请美国的博士是在 11 年,但拿到的 offer 并没有特别合适的导师,于是就北上投奔文渊去了。 我当时在百度商务搜索部门做广告的点击预估。具体是使用机器学习来预测一个广告是不是会被用户点击。 这时候离“大数据”这个词流行还有两年,但百度那时候的数据即使现在来看仍然是大的。我的任务是如何高效的利用数百台机器快速的在数十 T 的数据上训练出模型。</p>\n<p>当时产品用的算法基于 LBFGS,我于是想是不是可以换个收敛更快的算法。没几天就找到个不错 。但实现上发现了各种问题,包括性能,收敛,和稳定性。而且那时有的就是一个裸的 Linux 和很老版本的 GCC,什么都是需要从头开始写。花了大量时间做系统优化,算法改动,和线上实验,最后一年后在整个广告流量上上了线。</p>\n<p>现在再回顾会觉得整个一年时间都在打磨各种细节上,有时候为了 5%的性能提升花上上千行代码。这些都导致算法过于复杂,有过度设计之嫌。但深入各个细节对个人能力提升很大,而且很多遇到的问题成为了之后研究方向的来源。一些算法上的思考曾写在<a class=" wrap external" href="http://link.zhihu.com/?target=http%3A//mli.github.io/2013/03/24/the-end-of-feature-engineering-and-linear-model/" rel="nofollow noreferrer" target="_blank">这里</a>,当时候深度学习刚刚出来,冥冥中觉得这个应该是大规模机器学习的未来,不过真正开始跟进是好几年以后了。</p>\n<p>11 年 12 月中的时候突然心血来潮随手把材料重新寄了一遍,就选了 CMU 和 MIT,结果意外收到了 CMU 的 offer。有天在百度食堂同凯哥(余凯)和潼哥(张潼)吃饭,我说收了 CMU offer,在纠结去不去。他们立马说去跟 Alex Smola 啊,他要要加入 CMU 了,我们给你引荐下。</p>\n<p>记得是离开的前一天才开始打包行李,早上去公司开完会,中午离职,跟小伙伴打招呼说出个国,然后就奔机场了。那天北京天气特别好,完全不记得前一天雾霾刚爆了表。</p>\n<p><strong>第一年:9/12-8/13</strong></p>\n<p>第一年的主要事情是熟悉环境和上课。CMU 课程比较重,博士需要学 8 门课,每门课工作量巨大。而且要求做两门课助教,做助教比上课更累。</p>\n<p>这一年上的课中对我最有用的是“高级分布式系统”。之前在上交 ACM 班的时候已经学过很多质量都还不错课,纯知识性的课程一般对我帮助不大。但这门课主要是读论文,然后大家讨论。不仅仅是关于知识,很多是对设计理念的领悟。大家知道对于系统而言,设计是一门艺术而不是科学,这是设计者审美和哲学理念的体现。同时系统界历史也是由一波又一波的潮流组成,了解历史的发展以及其中不断重复的规律非常有意义。</p>\n<p>那年这门课上课老师是 Hui Zhang(神人之一,20 多岁就在 CMU 任教了,学生包括了 Ion Stoica,他是 Spark 作者 Matei 的导师),他有非常好的大局观,对于“Why”这个问题阐述非常到位。我是通过这门课才对分布式系统有了比较清晰的认识。两年之后我偶然发现我的一篇论文也在这门课的阅读列表里了,算是小成就达成 。</p>\n<p>除了上课,更重要是做研究。我去 CMU 的时候 Alex 那时还在 Google,而且没经费,所以把我丢给了 Dave Andersen。于是我有了两个导师,一个做机器学习,一个做分布式系统。</p>\n<p>前面半年都是在相互熟悉的过程。我们每周会一起聊一个小时。前半年因为 Alex 不在,所以我们只能视频。Alex 那边信号经常不好,而且他有德国和澳大利亚口音,外加思维跳跃,经常我听不懂他说啥只能卖萌傻笑。还是靠着 Dave 不断的打字告诉我 Alex 说了什么才度过了前几次的会。</p>\n<p>两个导师风格迥异。Alex 是属于反应特别快,通常你说一点,他已经想好了接下来十点,要跟上他节奏很难。一般抛出问题的时候他就想好了好几个解决方法。这时候要证明自己的想法比他的更好不容易,需要大量的沟通和实验数据支撑。我想我大概是花了两年证明了在某些方向上我的方案一般更好,所以这时候他就不那么 hands-on 了。</p>\n<p>Dave 不会给很多想法,但会帮助把一个东西理解透,然后讲得很清楚。因为我研究方向主要是机器学习上,基本上前两年基本都是我在教 Dave 什么叫机器学习,而且是尽量不用公式那种教法。</p>\n<p>我的第一个研究工作是关于如果划分数据和计算使得减少机器学习求解中的网络通讯量。Alex 体现了他的强项,几分钟就把问题归纳成了一个优化问题,然后我们三各自提出一个解法。我做了做实验发现 Dave 的算法更好。接下来两个月把算法做了很多优化,然后又做了点理论分析就把论文写了。</p>\n<p>可惜这个想法似乎有点超前,虽然我们一遍又一遍的改进写作,但投了好几个会审稿人就是不理解,或者觉得这个问题不重要。那个时候学术界已经开始吹嘘“大数据”,但我觉得其实大部分人是不懂的,或者他们的“大数据”仍然是几个 GB 的规模,烤 U 盘需要十来分钟的那种。</p>\n<p>这是我在 CMU 的一个工作,我觉得挺有用,但却是唯一没能发表的。</p>\n<p>当时跟我坐同一个办公室的是 Richard Peng,他做的是理论研究。我经常跟他讨论问题,然后有了些想法合作了一个工作。大体思想是把图压缩的快速算法做到矩阵的低秩近似上。这个工作写了三十页公式但没有任何实验,我主要当做写代码间隙的悠闲娱乐,不过运气很好的中了 FOCS。</p>\n<p>坦白说我不是特别喜欢纯理论这种,例如在 bound 的证明中很多大量的项直接丢掉了,导致我觉得 bound 特别的近似。对于做系统的人来说,最后拼的是常数。这个工作中这种大开大合的做法我觉得很不踏实。所以我觉得以后还是应该做更实在点的东西。</p>\n<p>在 CMU 回到了去百度前的一周七天工作无休的节奏。每周至少 80 个小时花在学校。如果累了就去健身房,我一般晚上 12 点去。不仅是我一个人,大家都很努力,例如凌晨的健身房,早 3 点的办公室,四处都可以见到中国或者印度学生。我那时候的室友田渊栋花在学校的时候比我多很多。</p>\n<p>那一阵子有读了很多关于优化的文章。其中对我启发最大的是 Bertsekas 写于 80 年代末的那本关于分布式计算的书。此书可以认为是 MIT 控制领域黄金一代研究成果总结,换到现在仍然不过时。</p>\n<p>受启发我转去研究异步算法,就是分布式下不保证数据的及时性来提升系统性能。我基于在百度期间做的算法,做了一些改进和理论分析,然后投了 NIPS。</p>\n<p>投完 NIPS 就动身去了 Google Research 实习。那时候 Google Brain 成立不久,在“宇宙的答案”42 楼,包括 Jeff Dean,Geoffrey Hinton,Prabhakar Raghavan 好些大牛挤在一起,加起来论文引用率能超 80 万。</p>\n<p>Alex 跟我说,你去读读 Jure Leskovec 的文章,学学人家怎么讲故事。我在 Google 也尝试用了些用户 GPS 数据来对用户行为建模。可是写文章的时候怎么也写不出 Jure 的那种故事感,发现自己不是那块料。这篇文章因为用了用户数据,恰逢 Snowden 让大家意识到隐私的重要性,历经艰辛删了一半结果 Google 才允许发出来。有些累觉不爱。</p>\n<p>不过在 Google 期间我主要时间花在研究内部代码和文档上。Google 的基础架构很好,文档也很健全。虽然没有直接学到了什么,但至少是开了眼界。</p>\n<p><strong>第二年:9/13-8/14</strong></p>\n<p>这学期上了 Tuomas Sandholm 的机制设计,此乃另一大神,例如最近德州扑克赢了专业选手,之前开公司也卖了上亿。不过这门课我是完完全全没学懂,连承诺的课程大作业都没怎么做出来。之后的两年里我一遇到 Tuomas 他都会问下有什么进展没。我只能远远看见他就绕开。</p>\n<p>NIPS 被拒了,发现审稿人不懂线程和进程的区别,有点沮丧。隔壁实验室一篇想法类似但简单很多的论文倒是中了 oral,所以那阵子压力很大。Alex 安慰说这种事情常有发生,看淡点,然后举了很多自己的例子。</p>\n<p>之后想了想,一篇好文章自然需要有足够多的“干货”,或者说信息量, 但一篇能被接受的文章需要满足下面这个公式:</p>\n<blockquote>文章的信息量 / 文章的易读性 &lt; 审稿人水平 * 审稿人花的时间</blockquote>\n<p>对于机器学习会议,因为投稿量大,所以审稿人很多自然平均水平就会下降。而且很多审稿人就花半个小时到一个小时来读文章,所以公式右边数值通常是很小,而且不是我们能控制。</p>\n<p>如果文章的信息量不大,例如是改进前面工作或者一些简单的新想法,那么公式成立的概率很大。而对于信息量大的文章,就需要努力提升易读性,包括清晰的问题设定,足够的上下文解释等等。而前面投的那篇 NIPS,以及更早的那个被拒工作,就是因为我们假设了审稿人有足够多的相关专业知识,而我们塞进了太多干货使得大家都读糊涂了。</p>\n<p>即使对于已经发表的文章,上面那个公式同样可以用来衡量一篇论文的引用率。例如经常见到干货很多的文章没有什么人引用,而同时期的某些工作就是考虑了其中简单特殊情况结果被大引特引。</p>\n<p>接下来的半年我主要在做一个通用的分布式机器学习框架,是想以后做实验方便些。名字就叫 parameter server,沿用了 Alex 10 年论文提出的名字。花了很多时间在接口设计上,做了好几个版本实现,也跑了些工业界级别的大规模的实验。</p>\n<p>不过真正花了我大量时间的是在写论文上。目标是把这个工作投到 OSDI 上,OSDI 是系统界两大会之一。我们预计审稿人跟 Dave 两年前状态差不多,不会有太多机器学习和数学背景,所以需要尽量的少用公式。整整一个月就花在写论文上,14 页的文章满满都是文字和示意图。不过努力没有白费,最终论文被接受了。随后又花了好几周准备大会报告上。相对于平时花一周写论文,两三天准备报告,这次在写作和报告水平上有了很大的提升。没有放进去的公式和定理投了接下来的 NIPS,这次运气很好的中了。</p>\n<p>有了文章后稍微心安了点可以更自由的做些事情。</p>\n<p>寒假回了趟国,跑去百度找了凯哥和潼哥。潼哥说他最近有个想法,于是快糙猛的把实验做了然后写了篇论文投了 KDD。同时期 Alex 一个学生也把他一个一直想让我做但我觉得这个小 trick 不值得我花时间的想法投了 KDD,结果中了最佳论文。作报告那天我在的会场稀稀疏疏几个人,他们隔壁会场人山人海。这个使得好长一段时间我都在琢磨是不是还是要跟着导师走比较好。</p>\n<p>那时凯哥在百度搞少帅计划,觉得蛮合适就加入了。这时凯哥正带着一大帮兄弟轰轰烈烈的搞深度学习,我自然也是跳坑了。试过好几个想法后,我觉得做做分布式的深度学习框架比较对胃口。我挑了 CXXNet 作为起点,主要是因为跟天奇比较熟。同时也慢慢上手跑一些 Alexnet 之类的实验。</p>\n<p>我是因为少帅计划才开始开始做深度学习相关项目,凯哥也很支持我做开源开发回馈社会而不是只做公司内部的产品。但在少帅期间并没有做出什么对公司有帮助的事,很是惭愧。</p>\n<p><strong>第三年:9/14-8/15</strong></p>\n<p>回 CMU 后 Alex 看见深度学习这么火,说我们也去买点 GPU 玩玩。但我们比较穷,只能去 newegg 上掏点便宜货。这个开启了轰轰烈烈的机器折腾之旅。整个一年我觉得我都在买买买装装装上。最终我们可能就花了小几万刀攒出了一个有 80 块 GPU 的集群。现在想想时间上花费不值得,而且为了图便宜买了各种型号的硬件导致维护成本高。但当时候乐在其中。具体细节可以看这篇\xa0<a class=" wrap external" href="http://link.zhihu.com/?target=http%3A//mli.github.io/gpu/2016/01/17/build-gpu-clusters/" rel="nofollow noreferrer" target="_blank">blog</a></p>\n<p>这一年写了很多 parameter server 代码,同时花了很时间帮助用户使用这些代码。很难说做得很成功,现在想想有几个原因。写代码时我会优先考虑性能和支持最多的机器学习算法。但正如前面的错误,忽略了代码的易读性,从而导致只有少部分人能理解代码从而做一些开发。例如我尝试让 Alex 组的学生来使用这些代码,但其中的各种异步和 callback 让他们觉得很是难懂。其次是没有人能一起审核代码接口,导致这些接口有浓浓的个人味道,很难做到对所有人都简单明了。</p>\n<p>不过幸运的是找到一帮志同道合的小伙伴。最早是我发现天奇在写 xgboost 的分布式启动脚本,我看了看发现挺好用,就跟他聊了聊。聊下的发现有很多基础部件例如启动脚本,文件读取应该是可以多个项目共同使用,而不是每个项目都造一个轮子。于是跟天奇在 Github 上创建了一个叫 DMLC 的组织,用来加强合作和沟通。第一个项目是 dmlc-core,放置了启动和数据读取代码。</p>\n<p>DMLC 的第二个新项目叫 wormhole。想法是提供一系列分布式机器学习算法,他们使用差不多相同的配置参数来统一用户体验。我把 parameter server 里面的机器学习相关算法移植了过来,天奇移植了 xgboost。Parameter server 原有的系统代码简化到了 ps-lite。</p>\n<p>中途我听百度同学说 factorization machine(FM)在广告数据上效果不错,所以在 wormhole 上实现了下。针对分布式做了一些优化,然后投了 WSDM。前后没有花到一个月,但神奇的竟然拿了最佳论文提名。</p>\n<p>在 wormhole 的开发中发现一个问题,就是各个算法还是挺不一样,他们可以共用一些代码,但又有各自的特点,需要特别的优化来保证性能。这样导致维护有些困难,例如对共用代码的改动导致所有项目都要检查下。总结下来觉得一个项目最好只做一件事情。所以天奇把 xgboost 代码放回原来项目,我也把 FM 独立出来一个项目叫 difacto。</p>\n<p>通过一系列的项目,我学到的一点是,以目前的水平和人力,做一个通用而且高效的分布式机器学习框架是很难的一件事情。比较可行的是针对一类相似的机器学习算法做针对性的项目。这个项目的接口必须是符合这类算法结构,所以做算法开发的同学也能容易理解,而不是过多暴露底层系统细节。</p>\n<p>真正的让 DMLC 社区壮大的项目是第三个,叫做 MXNet。当时的背景是 CXXNet 达到了一定的成熟度,但它的灵活性有局限性。用户只能通过一个配置项来定义模型,而不是交互式的编程。另外一个项目是 zz 和敏捷他们做的 Minerva,是一个类似 numpy 的交互式编程接口,但这个灵活的接口对稳定性和性能优化带来很多挑战。我当时候同时给两个项目做分布式的扩展,所有都有一定的了解。然后一个自然的想法是,把两个项目合并起来取长补短岂不是很好。</p>\n<p>召集了两个项目的开发人员讨论了几次,有了大致的眉目。新项目取名 MXNet,可以叫做 mixed-net,是前面两个名字(Minerva 和 CXXNet)的组合。放弃开发了几年的项目不是容易的决定,但幸运的是小伙伴都愿意最求更好,所以 MXNet 进展挺顺利。很快就有了可以跑的第一个版本。</p>\n<p><strong>第四年:9/15-8/16</strong></p>\n<p>前半年为 difacto 和 MXNet 写了很多代码。其实一开始的时候我觉得 difacto 更重要些,毕竟它对于线性算法的提升非常显著而且额外的计算开销并不大,这对广告预估之类的应用会有非常大的提升。但有次遇到 Andrew Ng,我跟他说我同时在做这两个项目,他立即告诉我我应该全部精力放在 MXNet 上,这个的未来空间会大很多。我一直很佩服 Andrew 的眼光,所以听了他的建议。</p>\n<p>11 月的时候 MXNet 就有了很高的完成度。写了个小论文投去了 NIPS 的 workshop 也算是歇了口气。但随后就听到了 TensorFlow(TF)开源的消息。由 Jeff Dean 领导大量全职工程师开发,Google 庞大的宣传机器支持,不出意料迅速成为最流行的深度学习平台。TF 对我们压力还是蛮大,我们有核心开发者转去用了 TF。不过 TF 的存在让我领悟到一点,与其过分关心和担忧对手,不如把精力集中在把自己的做得更好。</p>\n<p>NIPS 的时候 MXNet 的小伙伴聚了一次,有好几个我其实是第一次见面。随后 Nvidia 的 GTC 邀请我们去做报告。在这两次之间大家爆发了一把,做了很多地方的改进。同时用户也在稳步增长。我们一直觉得 MXNet 是小开发团队所以做新东西快这是一个优势,但随着用户增加,收到抱怨说开发太快导致很多模块兼容性有问题。有段时间也在反思要在新技术开发速度和稳定性之间做一些权衡。</p>\n<p>这时一夜之间大数据不再流行,大家都在谈深度学习了。</p>\n<p>我也花了很多力气在宣传 MXNet 和争取开发者上。包括微博知乎上吼一吼,四处给报告。在大量的点赞声中有些陶醉,但很多中肯的批评也让我意识到重要的一点,就是应该真诚的分享而不是简单的吹嘘。</p>\n<p>因为大量的媒体介入,整个深度学习有娱乐化的趋势。娱乐化的报道很多都只是一些简单信息,(有偏见)的观点,而没有太多干货。不仅对别人没营养,对自己来说也就是满足虚荣心。与其写这些简单的水文,不如静下心做一些有深度的分享,包括技术细节,设计思路,和其中的体会。</p>\n<p>此类分享一个容易陷入的误区是只关注自己做了什么,结果多么好。这些确实能证明个人能力,对于想重复这个工作的人来说会有很大帮助。但更多的人更关心的是适用范围在哪里,就是什么情况下效果会减弱;为什么结果会那么好;insight 是什么。这个需要更多深入的理解和思考,而不是简单的展示结果。</p>\n<p>这个对写论文也是如此。只说自己的结果比基线好多少只能说明这是不错的工作,但结果再好并不能意味这个工作有深度。</p>\n<p>深度学习的火热导致了各种巨资收购初创司不断。Alex 也有点按耐不住, 结果是他,Dave,Ash(曾经是 YahooCTO)和我合伙弄了一家公司,拿了几十万的天使投资就开工了。Alex 写爬虫,Dave 写框架,我跑模型,风风火火干了好一阵子。可惜中途 Dave 跑路去跟 Jeff 做 TF 了。后来这个公司卖给了一个小上市公司。再后来我们觉得这个公司不靠谱也就没考虑跟他们干了。</p>\n<p>第一次创业不能说很成功,从中学到几点:一是跟教授开公司一定要注意有太多想法但没死死的掐住一个做,二是找一堆兼职的博士生来干活不是特别靠谱,尤其是产品不明确的时候,三是即使要卖公司也一定要做一个产品出来。我们卖的时候给很多人的感觉是团队人太强但产品太弱,所以他们只想要人而已。四是试图想要通过技术去改变一个非技术公司是很难的事情,尤其是过于新的技术。</p>\n<p>然后我们就奔去折腾下一个公司。Ash 早财务自由所以想做一个大的想法,但这时 Alex 刚在湾区买了个房,有还贷压力,他选择去了 Amazon。于是算是胎死腹中。</p>\n<p>随后收到 Jeff 的邮件说有没有兴趣加入 Google,自然这是一个很诱人的机会。同时我觉得小的创业技术性强的公司是不错的选择。但从 MXNet 的发展上来书,去 Amazon 是最好选择之一。自己挖的坑,总是要自己填的。所以我以兼职的身份去了 Amazon,领着一帮小弟做些 MXNet 开发和 AWS 上深度学习的应用。</p>\n<p><strong>第五年:9/16-2/17</strong></p>\n<p>早在 15 年初 Alex 就表示我可以毕业了,但作为拖延晚期患者,迟迟没开始准备。这时候感觉不能再拖了,于是窝在湾区写毕业论文。Alex 觉得毕业论文应该好好写,但我对把前面都做完的东西再捣鼓写写实在是没兴趣,尤其是加州太阳那么好,大部分时间我都是躺在后院晒太阳。此时 B 站已经完全被小学生占领,这边买书也不方便,无聊之余刷了很多起点。然后还写了篇<a class="internal" href="https://zhuanlan.zhihu.com/p/23781756">炼丹文</a>。</p>\n<p>CMU 要求答辩委员会需要有三个 CMU 老师和一个学校外的。除了两个导师外,我找了 Jeff Dean 和刚加入 CMU 的 Ruslan Salakhutdinov. 结果 Russ 随后就加入了 Apple,整个委员会的人都在湾区了。Jeff 开玩笑说可以来 Google 答辩。可惜跟 CMU 争吵了好多次,还是不允许在校外答辩,而且必须要三个人委员会成员在场。这些限制导致答辩一拖再拖,而且临时加了 Barnabas Poczos 来凑人数。最后是 Jeff 的助理快刀斩乱麻的协调好了时间把所有东西定好了。没有她估计我还可以拖几个月。</p>\n<p>答辩的时候是一个比较奇异的状态,委员会里有 Google, Amazon, Apple 的 AI 负责人,剩下两个和我又分别在这三家公司兼职。这个反应了当下 AI 领域学术界纷纷跑去工业界的趋势。</p>\n<p>不过答辩这个事情倒是挺简单,跟平常做个报告没什么太多区别。一片祥和,即使 Russ 问了 MXNet 和 TensorFlow 哪家强这个问题也没有打起来。</p>\n<p>答辩后我问委员会说,我在考虑找个学术界的工作,有什么建议没。大家介绍了一大堆经验,不过大家都强调的一个重点是:学术界好忙好忙,而且好穷好穷,工业界的薪水(就差指自己脸了)分分钟秒掉 CMU 校长。你要好好想。</p>\n<p><strong>总结</strong></p>\n<p>答辩前一天的晚上,我想了两个问题,一个是“博士收获最大的是什么”,另一个是“如果可以重来会怎么办”。对于第一个问题,这五年时间自然学到了很多东西,例如系统的学习了分布式系统,紧跟了机器学习这五年的发展,写文章做幻灯片做报告水平有提升,代码能力也加强了些。自信上有所提高,觉得既可以做一流的研究,也可以写跟大团队 PK 的代码。只要努力,对手没什么可怕的。</p>\n<p>但更重要的是博士的五年的时间可以专注的把一些事情从技术上做到最好,做出新的突破,这个氛围没有其他地方能给予。</p>\n<p>第二个问题的一个选项是当年留在国内会怎么样? 当年百度的伙伴们多数现在都做得很好,都在引领这一波 AI 的潮流,甚至有好几个创造了上亿价值的公司。所以从金钱或者影响力角度来看,一直在工业界也不差,说不定现在已经是土豪了。</p>\n<p>不过我觉得还是会选择读博。赚钱以后还有大把时间可以,但是能花几年时间在某个领域从入门到精通甚至到推动这个领域发展的机会就一次。站在这个领域的高点会发现世界虽然很大,但其实其他领域也使用差不多的技术,有着同样的发展规律。博士期间领悟到的学习的方法可以在各个方向上都会大有作为。</p>\n<p>更重要的是理想和情怀。人一生要工作五十年,为什么不花五年来追求下理想和情怀呢?</p>\n\n</div>\n</div>\n</div>\n</div>\n</div>',
    'meta': {
        'spider.zhihu_daily.id': '9677554',
        'moear.cover_image_slug': 'https://pic1.zhimg.com/v2-67088b10dbe889fdfa64f7fd06b90b84.jpg'
    },
    'author': '李沐',
    'excerpt': '\n前言\n12 年 8 月提着一个行李箱降落在匹兹堡机场。没找住的地方,也不知道 CMU 应该怎么去。对未来一片迷茫,但充满乐观。 现在,刚完成了博士期间最后的一场报告,在同样的机场,不过是在等待离开的航班。\n回想过去的五年,是折腾的五年,也是自我感悟和提升的五年。这里我尝试记录这五年主要做过的事情和其中的感想,希望对大家有所启发。\n第 0 年:3/11-8/12\n我第一次申请美国的博士是在 11 年,但拿到的 offer 并没有特别合适的导师,于是就北上投奔文渊去了。 我当时在百度商务搜索部门做广告的点击预估。具体是使用机器学习来预测一个广告是不是会被用户点击。 这时候离“大数据”这个词流行还有两年,但百度那时候的数据即使现在来看仍然是大的。我的任务是如何高效的利用数百台机器快速的在数十 T 的数据上训练出模型。\n当时产品用的算法基于 LBFGS,我于是想是不是可以换个收敛更快的算法。没几天就找到个不错 。但实现上发现了各种问题,包括性能,收敛,和稳定性。而且那时有的就是一个裸的 Linux 和很老版本的 GCC,什么都是需要从头开始写。花了大量时间做系统优化,算法改动,和线上实验,最',
    'origin_url': 'http://daily.zhihu.com/story/9677554',
    'spider': 'zhihu_daily',
    'date': '2018-04-09 00:02:00',
    'title': '我去美国读博这五年'
}, {
    'content': '<div class="main-wrap content-wrap">\n<div class="headline">\n<div class="img-place-holder"></div>\n</div>\n<div class="content-inner">\n<div class="question">\n<h2 class="question-title">外星人对地球有哪些会令地球人大吃一惊的刻板印象?</h2>\n<div class="answer">\n<div class="meta">\n<img class="avatar" src="http://pic3.zhimg.com/076370fd5013e2b4f6540cb48784970e_is.jpg"/>\n<span class="author">钟钟,</span><span class="bio">曾因多情鞭美人,生怕酒醉累名马</span>\n</div>\n<div class="content">\n<p>我们决定搬给地球人「最佳花式烧开水奖」。</p>\n<p>评语:在茫茫宇宙之中,智慧种族获取能量的方式千奇百怪,烧开水在某些智慧种族也曾经出现过,但是没有一个象地球人这样热衷于烧开水的。</p>\n<p>我们决定搬这个奖给地球人的理由是:他们通过各种方式获得能源资源,比如木材,煤炭,石油,天然气,太阳能,核裂变,核聚变等,但这些能源资源的使用目的就是烧开水。</p>\n<p>现在有请地球人代表上台领奖!</p>\n<p>有请地球人代表发表获奖感言!</p>\n<p>地球人代表泪流满面:我们他妈的点错科技树了!</p>\n<hr/><p>评论区 @<a class="UserLink-link" href="https://www.zhihu.com/people/shen-yi-66-37" target="_blank">哈撒改</a>:各类发电站其实就是用各种能源把水烧成蒸汽。</p>\n</div>\n</div>\n<div class="answer">\n<div class="meta">\n<img class="avatar" src="http://pic2.zhimg.com/v2-c63acf4bfee1ab6ea934db78fa850605_is.jpg"/>\n<span class="author">霜霰,</span><span class="bio">学生</span>\n</div>\n<div class="content">\n<p>这问题下的多数回答也体现出地球人对外星人的刻板印象。</p>\n</div>\n</div>\n\n</div>\n<div class="question">\n<h2 class="question-title">你见过哪些「没什么鸟用」的APP?</h2>\n<div class="answer">\n<div class="meta">\n<img class="avatar" src="http://pic1.zhimg.com/da8e974dc_is.jpg"/>\n<span class="author">知乎用户,</span><span class="bio">vox populi, vox dei.</span>\n</div>\n<div class="content">\n<p>你永远不知道 deadline 能把人逼成什么样。</p>\n<p>上学期学了一门安卓开发,课上到三分之一要开始项目提案了。</p>\n<p>那时我们刚学了 sensor,看了一下安卓的 sensor 文档,里面有一项是温度。</p>\n<p>那时我沉迷烘焙,老想烤个蛋糕烤个鸡。但是又葛朗台附体,舍不得买个烤箱温度计。</p>\n<p>于是我用无比严肃的语调和组员做提案。要不然写一个安卓温度烤箱计……</p>\n<p>同学们都用「诶,有点儿意思」的表情看向我。</p>\n<p>我说:「……利用安卓的温度传感,在屏幕上实时显示烤箱温度。用的方法很简单,启动 app 放进烤箱就好了。」</p>\n<p>同学用鼓励的神情让我继续发言。</p>\n<p>「……缺点就是只能用一次,并且要时不时地趴在烤箱前面读数。因为指不定下一秒手机就糊了。当然我们也可以加入语音播报……」</p>\n</div>\n</div>\n\n</div>\n<div class="question">\n<h2 class="question-title">外国人第一次喝中国白酒是种怎样的体验?</h2>\n<div class="answer">\n<div class="meta">\n<img class="avatar" src="http://pic1.zhimg.com/e49a657d4014162887a245d3039e4478_is.jpg"/>\n<span class="author">蒋占山,</span><span class="bio">非洲扛把子,吴彦祖plus。</span>\n</div>\n<div class="content">\n<p><img alt="" class="content-image" src="http://pic3.zhimg.com/70/v2-e4dc6e1ec400233106cf31aea41ff0f6_b.jpg"/></p>\n<p>我差点把赞比亚矿业部部长,喝进重病监护室,我会乱讲?!</p>\n<p><img alt="" class="content-image" src="http://pic4.zhimg.com/70/v2-04d82fcab9f164546274f7c61b4d5e67_b.jpg"/></p>\n<p>上面的图,是当地干警,来调查具体情况的图片。</p>\n<p>没错,我第二天七点起来上班了。</p>\n<p>没错,这位大胸 dei 误以为我要下毒害他……</p>\n<p>\xa0</p>\n<p>为什么我不中途阻止他?</p>\n<p>因为黑人喝酒不上脸啊!!!</p>\n<p>不接受任何反驳。</p>\n<p><img alt="" class="content-image" src="http://pic3.zhimg.com/70/v2-497aa873dc6a686ef74bc81f6ae63d0a_b.jpg"/></p>\n<p>赞比亚捕快带的武器里面,没有子弹的。</p>\n<p>他们是两个人一组,一个人拿武器,带一个空弹夹。</p>\n<p>一人带弹夹,有子弹。</p>\n<p>很唬人的。ლ(╹◡╹ლ)</p>\n</div>\n</div>\n\n</div>\n</div>\n</div>',
    'meta': {
        'spider.zhihu_daily.id': '9677635',
        'moear.cover_image_slug': 'https://pic4.zhimg.com/v2-90b133da744defcff96e9efdcd4f39f3.jpg'
    },
    'author': '知乎用户,钟钟,霜霰,蒋占山',
    'excerpt': '\n我们决定搬给地球人「最佳花式烧开水奖」。\n评语:在茫茫宇宙之中,智慧种族获取能量的方式千奇百怪,烧开水在某些智慧种族也曾经出现过,但是没有一个象地球人这样热衷于烧开水的。\n我们决定搬这个奖给地球人的理由是:他们通过各种方式获得能源资源,比如木材,煤炭,石油,天然气,太阳能,核裂变,核聚变等,但这些能源资源的使用目的就是烧开水。\n现在有请地球人代表上台领奖!\n有请地球人代表发表获奖感言!\n地球人代表泪流满面:我们他妈的点错科技树了!\n评论区 @哈撒改:各类发电站其实就是用各种能源把水烧成蒸汽。\n \n这问题下的多数回答也体现出地球人对外星人的刻板印象。\n \n你永远不知道 deadline 能把人逼成什么样。\n上学期学了一门安卓开发,课上到三分之一要开始项目提案了。\n那时我们刚学了 sensor,看了一下安卓的 sensor 文档,里面有一项是温度。\n那时我沉迷烘焙,老想烤个蛋糕烤个鸡。但是又葛朗台附体,舍不得买个烤箱温度计。\n于是我用无比严肃的语调和组员做提案。要不然写一个安卓温度烤箱计……\n同学们都用「诶,有点儿意思」的表情看向我。\n我说:「……利用安卓的温度传感,在屏幕上实时显示烤箱',
    'origin_url': 'http://daily.zhihu.com/story/9677635',
    'spider': 'zhihu_daily',
    'date': '2018-04-09 00:01:00',
    'title': '瞎扯 · 如何正确地吐槽'
}])])
结构说明

返回包为一个有序字典 collections.OrderedDict ,内容为以章节名为 Key 的文章列表,文章列表中的内容即为 ZhihuDaily.crawl() 返回的文章内容,消化掉元数据中相应专用字段后的数据

入口模块

class moear_spider_zhihudaily.entry.ZhihuDaily(*args, **kwargs)[源代码]

基类:moear_api_common.base.SpiderBase

知乎日报爬虫插件

初始化默认配置参数,可在子类中进行覆盖

配置优先级为:用户元数据 > 具体Package配置 > Common全局默认配置

参数:usermeta (dict) – (可选,关键字参数)指定用户的package相关配置元数据, 如:定制书籍名(book_title)等
hook_custom_options()[源代码]

该方法返回当前类的自定义配置项,由基类在 __init__ 方法中调用, 调用点位于,Common默认全局配置完成后,用户元数据配置前

返回:返回当前类的自定义配置项
返回类型:dict
register(*args, **kwargs)[源代码]

调用方可根据主键字段进行爬虫的创建或更新操作

返回:返回符合接口定义的字典数据
返回类型:dict
crawl(*args, **kwargs)[源代码]

执行爬取操作,并阻塞直到爬取完成,返回结果数据。 此处考虑到 Scrapy 本身的并发特性,故通过临时文件方式做数据传递, 将临时路径传递到爬虫业务中,并在爬取结束后对文件进行读取、 JSON 反序列化,返回

返回:返回符合接口定义的字典对象
返回类型:dict
format(data, *args, **kwargs)[源代码]

将传入的Post列表数据进行格式化处理。此处传入的 data 格式即为 ZhihuDaily.crawl() 返回的格式,但具体内容可以不同,即此处保留了灵活度, 可以对非当日文章对象进行格式化,制作相关主题的合集书籍

参数:data (list) – 待处理的文章列表
返回:返回符合mobi打包需求的定制化数据结构
返回类型:dict

爬虫模块

class moear_spider_zhihudaily.spiders.zhihu_daily.ZhihuDailySpider(date=None, *args, **kwargs)[源代码]

基类:scrapy.spiders.Spider

知乎日报爬虫类,用于爬取&解析知乎日报页面&相关协议

参数:
  • date (str) – 爬取日期,命令行参数,默认为空,即爬取当日最新,内容格式:yyyymmdd
  • output_file (str) – (可选,关键字参数)结果输出文件, 用以将最终爬取到的数据写入到指定文件中,默认为 moear_spider_zhihudaily 下的 build 路径,建议仅作为测试时使用
name = 'zhihu_daily'

来源名称,唯一,长度<255,用于文章源模型索引创建后不可修改

display_name = '知乎日报'

显示名称,长度<255,Spider每次运行时更新

author = '小貘'

组件作者,Spider每次运行时更新

email = 'moore@moorehy.com'

组件作者邮箱,Spider每次运行时更新

description = '每天三次,每次七分钟。在中国,资讯类移动应用的人均阅读时长是 5 分钟,而在知乎日报,这个数字是 21'

描述信息,长度无限制,Spider每次运行时更新

parse(response)[源代码]

根据对 start_urls 中提供链接的请求响应包内容,解析生成具体文章链接请求

参数:response (Response) – 由 Scrapy 调用并传入的请求响应对象
parse_post(response)[源代码]

根据 ZhihuDailySpider.parse() 中生成的具体文章地址,获取到文章内容, 并对其进行格式化处理,结果填充到对象属性 item_list

参数:response (Response) – 由 Scrapy 调用并传入的请求响应对象
closed(reason)[源代码]

异步爬取全部结束后,执行此关闭方法,对 item_list 中的数据进行 JSON 序列化,并输出到指定文件中,传递给 ZhihuDaily.crawl()

参数:reason (obj) – 爬虫关闭原因

知乎API分析

声明

提示

以下知乎日报协议分析主要参考于 知乎日报 API 分析 ,针对于部分协议进行了额外的验证和补充,以及实际爬取的逻辑阐述,侵删

重要

感谢 Xiao Liang 前辈的贡献 Orz,正愁无门路打算直接硬抓Web版文章信息的时候, 看到您的这篇分析文章,如醍醐灌顶一般,整个人瞬间精神了!

API 说明

  • 本协议分析主要针对于知乎日报第 4 版 API,且主要关注于文章相关内容获取部分, 其余更全面的部分,如:启动界面、软件版本、评论相关、主题日报等 APP 相关协议可参考上述链接
  • 以下所有 API 使用的 HTTP Method 均为 GET

API 分析

最新消息

请求链接

GET http://news-at.zhihu.com/api/4/news/latest

响应实例
{
    "date": "20161201",
    "stories": [{
        "images": ["http://pic1.zhimg.com/1336c8a5e842c11912014f093cc69d58.jpg"],
        "type": 0,
        "id": 9026396,
        "ga_prefix": "120111",
        "title": "收了的税全部返还,民众福利怎么就大大下降了?"
    }
    ...
    ],
    "top_stories": [{
        "image": "http://pic4.zhimg.com/8fc4831c28432f700b6400de882fd833.jpg",
        "type": 0,
        "id": 9022827,
        "ga_prefix": "120113",
        "title": "爱看《冰与火之歌》和《魔戒》,没想到背后这么多八卦"
    },
    ...
    ]
}
字段分析
date
日期
stories

当日新闻

title
新闻标题
images
图像地址(官方 API 使用数组形式。目前暂未有使用多张图片的情形出现,曾见无 images 属性的情况 ,请在使用中注意 )
ga_prefix
供 Google Analytics 使用
type
作用未知
id
urlshare_url 中最后的数字(应为内容的 id)
multipic
消息是否包含多张图片(仅出现在包含多图的新闻中)
top_stories
界面顶部 ViewPager 滚动显示的显示内容(子项格式同上)(请注意区分此处的 image 属性与 stories 中的 images 属性)
补充信息
  1. images 字段不存在的情况,如:《8 月 1 日,这些新闻值得你了解一下》 ,获取到的列表项内容为:

    {
        "type": 0,
        "id": 4065555,
        "ga_prefix": "010115",
        "title": "8 月 1 日,这些新闻值得你了解一下"
    }
    
  2. top_stories.image 字段中的图片为APP中的顶部轮播图使用,故分辨率会比 stories 中的相同文章块 images 里的图片拥有更高的分辨率,一般情况下,前者为 640*640,而后者仅为 150*150。故在做文章爬取时可以根据实际需求进行选择,下节将说明如何获取非热文的高质量封面图

消息内容获取与离线下载

请求链接

GET http://news-at.zhihu.com/api/4/news/9026396

  • 使用在 最新消息 中获得的 id,拼接在 http://news-at.zhihu.com/api/4/news/ 后,得到对应消息 JSON 格式的内容
响应实例
{
    "body": "...页面具体内容的html部分...",
    "image_source": "韦你好 / 知乎",
    "title": "瞎扯 · 如何正确地吐槽",
    "image": "http://pic3.zhimg.com/ab8cb35b812c249dff4cfd8cd5bd1056.jpg",
    "share_url": "http://daily.zhihu.com/story/9024081",
    "js": [],
    "ga_prefix": "120106",
    "section": {
        "thumbnail": "http://pic3.zhimg.com/9c7eebeb525f7f9135fd961080b80a2e.jpg",
        "id": 2,
        "name": "瞎扯"
    },
    "images": ["http://pic3.zhimg.com/9c7eebeb525f7f9135fd961080b80a2e.jpg"],
    "type": 0,
    "id": 9024081,
    "css": ["http://news-at.zhihu.com/css/news_qa.auto.css?v=4b3e3"]
}
字段分析
body
HTML 格式的新闻
image-source
图片的内容提供方。为了避免被起诉非法使用图片,在显示图片时最好附上其版权信息。
title
新闻标题
image
获得的图片同 最新消息 获得的图片分辨率不同。这里获得的是在文章浏览界面中使用的大图。
share_url
供在线查看内容与分享至 SNS 用的 URL
js
供手机端的 WebView(UIWebView) 使用
recommenders
这篇文章的推荐者
ga_prefix
供 Google Analytics 使用
section

栏目的信息

thumbnail
栏目的缩略图
id
该栏目的 id
name
该栏目的名称
type
新闻的类型
id
新闻的 id
css

供手机端的 WebView(UIWebView) 使用

  • 可知,知乎日报的文章浏览界面利用 WebView(UIWebView) 实现

注意

在较为特殊的情况下,知乎日报可能将某个主题日报的站外文章推送至知乎日报首页。

响应实例:

{
    "theme_name": "电影日报",
    "title": "五分钟读懂明星的花样昵称:一美、法鲨……",
    "share_url": "http://daily.zhihu.com/story/3942319",
    "js": [],
    "ga_prefix": "052921",
    "editor_name": "邹波",
    "theme_id": 3,
    "type": 1,
    "id": 3942319,
    "css": [
        "http://news.at.zhihu.com/css/news_qa.6.css?v=b390f"
    ]
}

此时返回的 JSON 数据缺少 bodyimage-sourceimagejs 属性。 多出 theme_nameeditor_nametheme_id 三个属性。 type0 变为 1

补充信息
  1. 文章爬取时主要使用 body (内容), image ( 高清封面图 ), share_url (文章url), title (标题)
  2. 另外需要对 type 进行判断,若为 1 ,则另行处理
  3. recommenders 字段非常驻字段,即不一定存在

过往消息

请求链接

GET http://news-at.zhihu.com/api/4/news/before/20131119

  • 若果需要查询 11 月 18 日的消息, before 后的数字应为 20131119
  • 知乎日报的生日为 2013 年 5 月 19 日,若 before 后数字小于 20130520 , 只会接收到空消息
  • 输入的今日之后的日期仍然获得今日内容,但是格式不同于最新消息的 JSON 格式
响应实例
{
    "date": "20131118",
    "stories": [{
        "images": ["http://p4.zhimg.com/7b/c8/7bc8ef5947b069513c51e4b9521b5c82.jpg"],
        "type": 0,
        "id": 1747159,
        "ga_prefix": "111822",
        "title": "深夜食堂 · 我的张曼妮"
    },
    ...
    ]
}
字段分析

格式与前同,故不再赘述

补充信息
  1. 使用此接口获取的当日消息是不包含 top_stories 字段的, 仅含该日 date & stories 字段
  2. 一天的时间差需单独封装处理,通过获取到的文章id, 调用上述第二条API即可获取到相应文章的详细信息,如高清封面图等

代办事项

发布说明

v1.1.1 (2018-06-17 12:14:28)

Bugfix

  1. 修复由于知乎日报官方接口链接变更造成的无法正常获取到历史文章的 Bug

v1.1.0 (2018-06-17 11:20:32)

Feature

  1. 增加 ZhihuDaily.crawl 方法的调用多参传递,从而便于调试以及今后的爬取指定日期功能

v1.0.1 (2018-05-01 22:16:01)

Bugfix

  1. 修复摘要信息未转义造成最终 KindleGen 打包时错误的 Bug

Optimize

  1. 优化 Python 打包清单文件
  2. 优化针对 Sphinx 的依赖说明文件,便于 RTFD 构建文档
  3. 爬取时对标题&作者字串做 html 转义,避免打包时的构建错误

v1.0.0 (2018-04-09 17:52:01)

  1. 知乎日报文章爬取
  2. 对文章列表进行格式化,按是否 热闻 分类