标签归档:技术书

国内技术书盗版现状

我在 18 年出版了一本技术书,快两年过去了,和盗版打了很多交道。这篇文章从一个技术书作者的视角以 2018~2020 作为切片来记录一下国内技术书的盗版现状。

盗版的起源

我的书第一次上架到电子书平台是在 18 年 8 月 24 号,纸质书正式开始发售是在同年 9 月 13 号。仅仅不到一个月的时间,在 10 月初,淘宝上就开始出现了大量盗版影印书(大约有十几个,价格多在 ¥30 左右)。紧接着,在 11 月初,CSDN 上出现很多盗版电子书。同一时间,多个盗版电子书网站开始有了这本书,基本占领了百度和 Google 的前几页搜索结果。

SEO 赢家

从纸书发售的两个月后开始,一直到现在,不管在哪个搜索引擎上,盗版文件的链接都是 SEO 赢家。以 Google 为例,直接搜索书名「Flask Web开发实战:入门、进阶与原理解析」,前几页的盗版链接比例如下(四月末数据):

  • 第一页:4/10
  • 第二页:7/10
  • 第三页:5/10

单是直接搜索书名就已经得到这么高的盗版比例,更别说加上 PDF 之类的盗版关联词。

下面是在 Google 上的第一页搜索结果截图:

Google 搜索结果

书刚出版那段时间,盗版泛滥,但我能做的事情并不多。算是作为恶作剧,我在自己的博客上也放了一个盗版电子书下载页面(上面搜索结果里的第五位),复制了某个盗版电子书网站的标题和内容,特意用了中文 URL 和盗版关键词。本来是打算在页面结尾放下载链接的地方讽刺几句,嘲弄一下点进来想下载盗版电子书的笨蛋。但是又担心激怒了某个家伙,然后被到处写差评。而且这样也太没有气度,所以只是把下载链接指向了这本书的主页。

我的博客上的文章点击基本都是来自搜索引擎的自然流量,18 年 12 月 19 日发布的一篇无聊的技术文章到现在有 262 个点击,而第二天发布的这个盗版电子书下载文章有 2673 个点击:

盗版文章点击量

 

淘宝和闲鱼

淘宝是最早出现盗版影印书的地方,闲鱼其次。18 年集中处理了一批淘宝影印书,中间又零散处理一些,最近试着再次用关键词搜索,发现盗版影印书又开始卷土重来了。这是在淘宝使用关键词「Flask Web开发实战:入门、进阶与原理解析」得到的第一页结果(2020/5/23 数据),48 个商品里有 16 个是盗版影印书,刚好占据三分之一:

淘宝搜索结果大多盗版影印书都会打着二手的旗号卖盗版。以第一页里看起来最像是真二手的这家店为例(它甚至在商品介绍图片里清晰的注明「拒绝盗版」、「8 新正版二手」):

淘宝影印书

当你进一步询问,几乎总会得到这样的回答:

盗版影印书聊天对话

淘宝网站和闲鱼上自带的举报功能是没用的,即使商家有极其明显的售假描述,比如「PDF」、「影印」:

盗版商品描述

但是举报之后得到的举报结果总是固定不变的「从信息层面暂未能核实到售假信息」:

淘宝举报处理结果

对于淘宝和闲鱼的盗版书,更有效的方式是在阿里巴巴集团知识版权保护平台(https://ipp.alibabagroup.com/)提交投诉,不过每一件商品的投诉都要经历与客服/商家对话确认、生成阿里旺旺举证号、填写投诉单这样一个漫长的过程。慢慢的,我开始直接在对方承认售假后要求对方下架。大多数商家都是愿意合作的(偶尔有些商家在下架一段时间后会偷偷再次上架,这时再花时间在淘宝 IPP 平台提交投诉),所以那段时间用这种方式处理了一大批盗版影印书:

盗版影印书合影

虽然淘宝上的盗版影印书现在又大批量复活了,但我已经没有新书发售时那样的动力和愤慨心情去处理它们。

百度网盘

大部分独立站点售卖的盗版电子书都是放到百度网盘上的,这些独立站点的站长有些联系不上,有些拒绝删除,所以更直接的处理方式是在百度网盘上举报。

和淘宝类似,无论你提交多少次,百度网盘文件页面的举报功能是没用的。你需要在百度版权中心(http://copyright.baidu.com/)进行投诉,前前后后一共处理了 19 个盗版文件:

百度网盘投诉记录

但是这样做只对那些比较懒的盗版商人有用,因为勤劳的盗版商人总是会不停的更换掉失效的网盘链接,甚至每次都换一个相关性弱一点的名字,试图绕过百度网盘盗版审核的判断标准。我曾经连续四次跟踪举报某篇文章里的盗版网盘链接,对方把网盘的文件名从「《Flask Web开发实战入门进阶与原理解析》PDF+配套源代码+资料+参考」一直缩减到「Python Web 开发」。

这些电子书文件有很多版本,有一些是资源售卖者制作的不完整文件,最后一页会放一个购买方式,比如微信公众号或 QQ 号,还有一些会在最后放一个资源售卖网站的链接,你需要付费获取用来提取文件的密钥。他们还会像模像样的放一个这样的「版权声明」:

盗版电子书的版权声明

还有一些就是热心读者或者说乐于分享的读者自发分享出来的完整电子书文件,其中最完整的是一份 312M 的压缩包文件,其中包含了:

  • 一份从亚马逊 Kindle 客户端破解的 PDF 文件
  • 一份纸质书扫描版的 PDF 文件
  • 从 GitHub 下载的前六章源码
  • 一份包含对方盗版电子书资源网站信息的 TXT 文件

阿里云对象存储服务器

影响最大,最难处理的是阿里云服务器上的一个盗版文件。有人在阿里云的对象存储服务器上放了一个完整的 PDF 文件,而且这个文件在 Google 的搜索结果中排名非常靠前,这也就意味着任何人只要用 Google 搜索关键词,都可以直接点击链接在浏览器打开这个文件并下载。

在我没处理掉这个文件之前,它长期占据搜索引擎结果第一名的位置(使用次要关键词也会排在第三名):

盗版 PDF 的 Google 搜索排名

阿里云对象存储(OSS)是阿里云提供的存储服务,这个 PDF 文件存储在深圳区的阿里云服务器上,域名也是阿里云的域名(oss-cn-shenzhen.aliyuncs.com)。2020 年 3 月 2 号我在阿里云举报中心提交了一个举报,流程很麻烦,除了要提供身份证扫描件和著作权证明外,还要填一个列举各类证据和信息的承诺书,但是处理结果却很简单:

阿里云举报结果

先让我提供版权证明和列举侵权证据,最后却告诉我「除非接到法院判决或行政裁决,阿里云无权对侵权文件进行处理」。更好笑的是,建议我「直接通知该网站经营者或相关域名持有人并与之协商」,而这个盗版文件的「网站经营者和相关域名持有人」正是阿里云本身。

虽然声称「我方无权作出任何处置动作」,但是其 OSS 的服务条款里却清楚的注明了「阿里云有权采取相应的处理措施」:

「3.1.3.5.不利用阿里云提供的资源和服务上传(Upload)、下载(download)、储存、发布如下信息或者内容,不为他人发布该等信息提供任何便利(包括但不限于设置URL、BANNER链接等):

……

3.1.3.5.7.侵害他人合法权益的信息和/或其他有损于社会秩序、社会治安、公共道德的信息或内容;

……

3.1.3.11.如阿里云发现您违反上述条款的约定,有权根据情况采取相应的处理措施,包括但不限于立即终止服务、中止服务或删除相应信息等。如果第三方机构或个人对您提出质疑或投诉,阿里云将通知您,您有责任在规定时间内进行说明并出具证明材料,如您未能提供相反证据或您逾期未能反馈的,阿里云将采取包括但不限于立即终止服务、中止服务或删除相应信息等处理措施。因您未及时更新联系方式或联系方式不正确而致使未能联系到您的,亦视为您逾期未能反馈。」

我没法接受让一个盗版 PDF 文件直接出现在书名搜索结果的第一名。4 月 24 号,我在新闻出版广电总局的盗版举报平台(http://www.sapprft.gov.cn/sapprft/channels/6979.shtml)提交了对阿里云的举报。我想要是这也没用,那就只能起诉了。

结果某天正在写这篇文章的时候(这篇文章一直断断续续写了很久),多番尝试之后,搜索到了这个 OSS 仓库(Bucket)的拥有者放到 GitHub 上的相关代码,翻了下 commit 历史,竟然发现了被意外提交到 Git 仓库的 Access key ID 和密钥(用来登录阿里云 OSS 的认证信息):

GitHub 代码历史

所以,我就自己用这些认证信息登录阿里云 OSS 删掉了对方存储的盗版文件:

删除阿里云 OSS 文件

加上一个网络教程的 MP3 和 HTML 文件,这位同学一共存储了 400 多个盗版文件。我不是狂热的正版卫士,所以没有做出更大的破坏,只是删除了我的书。

也许更合理的方式是发电子邮件(他的 GitHub 资料上放了 Email 地址)请求他删除,但是既然他收到阿里云(如果阿里云的确通知了)的删除请求,但依然无所作为,而且这个文件困扰了我很长时间,自己删掉会让我觉得有报复的平衡……事后我发了邮件跟他说了这件事,结果对方很诚恳的道歉,倒让我因为「自己动手」有点不好意思。

技术博客和电子书网站

CSDN 的下载板块是盗版电子书的聚集地,还好我的书刚开始在 CSDN 传播的时候,出版社和 CSDN 协商删除了大部分文件,所以我不用跟 CSDN 有太多纠缠。

CSDN 下载页面

售卖电子书文件的人大都会在CSDN、博客园和 51CTO 上面发文章分享网盘链接,因为这三个站点的链接在搜索引擎上的排名都很靠前。51 CTO 和博客园上的文章都没有举报按钮,网站底部也没有投诉通道,所以你需要发邮件给网站方请求删除相关文章。

而对于各类专业的电子书资源网站,如果网站上有联系方式的话,那你可以直接联系站长,要求他们删除。如果站长什么也没留,那就没办法了。

有一个盗版网站的站长,我假装买电子书加上他的 QQ 后,他发给我一个包含大量技术书列表的 Excel 文件,意思是任我挑选。我问他你这样随便卖盗版电子书,假如大多数人都来买盗版,那作者拿不到钱不就没有人愿意写书了?

他告诉我说,他其实是从亚马逊买了正版电子书,破解以后便宜卖给别人,其实就相当于大家一起凑钱买了书(众筹?),这样大家都可以看到书。那一刻,我感觉对方心里有火也有光,仿佛面前是一个向无数编程学习者打开技术世界大门的武林前辈,一个带领大家走向共产新世界的先进同志。

多搜索几页,你会发现,这样热心伟大、一心只为人类进步,一本书只卖一块五的人,有很多:

盗版电子书网站

IM 群组和微信公众号

IM 群组尤其是 QQ 群也是盗版电子书的重灾区,技术相关的 QQ 群非常多,几乎每一个群里都有大量盗版电子书文件,有些还按照语言和框架整理的非常整齐:

QQ 群的盗版文件

这里的处理难题是,你没有时间和精力去申请加入每一个群,然后定期挨个检查有没有你的盗版书被上传。

去年年初,我也创建了一个 Flask 技术讨论 QQ 群,有趣的是,竟然会有人在群里分享我的书的电子书文件:

HelloFlask 群聊盗版电子书

微信群因为没有群文件功能,分享出来的盗版书影响相对要小一点。但还有很多技术相关的微信公众号靠分享盗版电子书来引流,每一个这类公众号都有不少关注者。

这种现状还会持续多久?

体面的生活里不应该存在盗版,何况是像书这种存在大量正版购买渠道的东西。但你很难让大多数人在匿名的网络空间里也保持现实中的道德感,而且还有很多人并不认为盗版有什么不对。

盗版读者越多,网络上的盗版资源商、淘宝影印书就会越来越多。搜索盗版关键词的人越多,盗版网站就会越来越多,排名也就越来越靠前。你关注分享盗版电子书的微信公众号,那靠分享盗版电子书吸引关注者的微信公众号就会越来越多。

与此同时,出版社和作者的收入就会越来越少,用心写书和出书的作者和出版社也会越来越少,有能力写出好书的人也就会更加犹豫要不要写书。无论盗版用户怎么辩驳, 盗版都是一件损害创作者和出版方利益的事情,最终也会影响整个技术写作环境和每一个人的阅读体验和选择。

百度知道盗版分享

看着这些礼貌的、充满对知识真诚的渴望和期盼的留言,我在想这种盗版现状还会持续多久?

我想不出答案。

P.S. 没有动物在本文写作过程中受到伤害,但是有 3 本淘宝影印盗版书、5 个百度网盘盗版电子书文件、一份阿里云 OSS 深圳服务器里的盗版文件,一篇博客园分享盗版的文章永远的离开了这个世界。

P.P.S 如果你没法访问 Google,请检查网线有没有正确连接,或打电话询问运营商,确认接入的是互联网而不是光明网。

相关链接:


Update 2020/7/30

QQ 上有一个群成员跟我私聊,说他在网上找到我的 Flask 教程,但是不知道解压密码,想问我密码是多少。我很疑惑,不知道他到底在说什么,所以让他发链接给我看看,结果他发过来一个盗版资源售卖网站的链接,链接解析信息写着:「本资料为最新整理的《Flask Web 开发实战》PDF+源代码,用于学习,内容丰富!」……

Update 2020/8/17

有读者在知乎上发现了别人新分享的盗版 PDF 分享文章,在 QQ 群里提醒我。我还没开始处理,已经有几个群友在文章下发评论要求删除,第二天作者自己删除了文章。

Update 2020/11/5

又在淘宝上发现大概二十多本影印书,价格大都在 25 左右。好奇下载了拼多多,搜索结果里 90% 都是盗版影印书。

我在一本技术书里放置的十个彩蛋

Flask Web 开发实战》已经出版一年多,书里面的一些彩蛋也不知道有多少被人发现了。再不公开,我可能都要忘了。所以就趁着出版一周年这个契机整理一下吧。

这些彩蛋大都是关于电影的一些双关和文字游戏,有一些说是彩蛋可能会有些勉强。比较正式的一共有 10 个,分别对应十部电影。也就是第三章介绍模板引擎时的实例程序电影清单里列出来的十部电影。

下面按照出现顺序一一剧透。

阿甘正传(Forrest Gump)

P14 第一章:初识 Flask 1.3

这一节介绍运行 Flask 程序,章节标题是「Run, Flask, Run!」。

阿甘正传里,当阿甘被欺负的时候,珍妮总会喊「Run, Forrest, Run!」。

blank

红白蓝三部曲(Three Colours trilogy)

P36 第二章:Flask 和 HTTP 2.2.3.3

介绍 URL 规则的 any 转换器时使用的示例如下:

@app.route('/colors/<any(blue, white, red):color>')
def three_colors(color):
    return '<p>Love is patient and kind. Love is not jealous or boastful or proud or rude.</p>'

这个并没有什么特殊含义,就是列了三个颜色作为 URL 选项,返回的都是圣经里的那句话。

电影清单

P76 第三章:模板

第三章在示例程序里的填充数据是整本书所有彩蛋相关的十部电影,作为一个足够显眼的线索。

movies = [
    {'name': 'My Neighbor Totoro', 'year': '1988'},
    {'name': 'Three Colours trilogy', 'year': '1993'},
    {'name': 'Forrest Gump', 'year': '1994'},
    {'name': 'Perfect Blue', 'year': '1997'},
    {'name': 'The Matrix', 'year': '1999'},
    {'name': 'Memento', 'year': '2000'},
    {'name': 'The Bucket list', 'year': '2007'},
    {'name': 'Black Swan', 'year': '2010'},
    {'name': 'Gone Girl', 'year': '2014'},
    {'name': 'CoCo', 'year': '2017'},
]

另外这个电影清单也有现实版:IMDb镜像豆列

寻梦环游记(CoCo)

P105 第四章:模板

这一章一开始给出了一个 HTML 登录表单的示例,示例代码和渲染后的画面(图 4-1)中,用户名输入框的占位文字是 Héctor Rivera,密码输入框的占位文字是 19001130,勾选了记住登录状态的「记住我(Remember me)」选项。

blank

Héctor Rivera 是电影里小男孩在亡灵世界里遇到的死去的爸爸,他的生日是 1900 年 11 月 30 日,勾选了「Remember me」,他就会被人记住,所以就不会消失了……

消失的爱人(Gone Girl)

P139 第五章:数据库

第一小节介绍关系型数据库的时候给出了一个示例表格(表 5-1),如下:

blank

这两条数据分别对应《消失的爱人》里的男女主角。

记忆碎片(Memento)

同样在第五章,这一章写了一个用来记笔记的示例程序,分别使用了三条笔记内容作为示例演示 CRUD 操作,即:

blank

这三条笔记均是《记忆碎片》里男主角记在各处的笔记。

中国发出的第一封电子邮件

P178 第六章:电子邮件

第六章介绍电子邮件使用的示例邮件正文是「Across the Great Wall we can reach every corner in the world.」。这是 1987 年从中国发出的第一封电子邮件正文。

本来是想把 Wall 换成另一个单词以便反映现状的,但是出于安全考虑,没那么做。不过这句话原版现在来看已经是够讽刺的了。

黑客帝国(The Matrix)

P246 第八章:个人博客

介绍自定义 flash 消息样式的时候,给出了下面的自定义 CSS 类示例:

.alert-matrix {
    color: #66ff66;
    background-color: #000000;
    border-color: #ebccd1; /* 这一行好像没用 */
}

调用示例如下:

flash('Knock, knock, Neo.', 'matrix')

实际的显示效果如下所示:

blank

模拟了电影原图:

blank

 

《未麻的部屋》(Perfect Blue)和《黑天鹅》(Black Swan)

P236 第八章:个人博客

这一章的示例博客名字叫做 Bluelog,模仿了《未麻的部屋》里记录未麻生活的网站,初始化账户的信息如下:

def fake_admin():
    admin = Admin(
        username='admin',
        blog_title='Bluelog',
        blog_sub_title="No, I'm the real thing.",
        name='Mima Kirigoe',
        about='Um, l, Mima Kirigoe, had a fun time as a member of CHAM...'
    )
    ...

另外介绍博客的主题地方提供了蓝色和黑色两个主题,主题名分别是「Perfect Blue」和「Black Swan」,对应《未麻的部屋》和《黑天鹅》两部电影的英文名(后者致敬了前者)。

龙猫(My Neighbor Totoro)

P260 第八章:个人博客

这个算不上彩蛋……在介绍生成英文标题 slug 的 slugify 函数的时候,实际调用的示例使用了龙猫的几种名字作为输入数据:

>>> slugify(u'My Neighbor Totoro')
u'my-neighbor-totoro'
>>> slugify(u'邻家的豆豆龙')
u'lin-jia-de-dou-dou-long'
>>> slugify(u'となりのトトロ')
u'tonarinototoro'

遗愿清单(The Bucket List)

P421 第十章:待办事项程序

这个彩蛋是刻意加的,因为这一章的示例程序是一个 Todo List 程序,所以要找一个和清单相关的电影。示例程序里的几条待办事项就是电影里的一些遗愿。当时还没看过这个电影,特意去看了一遍,感觉一般。

blank

应该就这些了,如果还有其他的,欢迎补充。

那么放置这些彩蛋的目的是?没目的……仅仅就是为了好玩。同时为了能让发现彩蛋的人也会觉得好玩。