维基百科:製作機器人

机器人是一种与维基百科互动的自动程序,就好像他们是人类编辑者一样。这个页面将解释如何制作一个用于维基百科的机器人。此页面主要适用于那些拥有编程经验,但不知道如何使用它们来创建维基机器人的用户。

为何需要机器人? 编辑

机器人以比人类快得多的速度执行任务。如果你需要完成一些简单但冗长的工作(比如当你需要添加模板到某个类别的1000多个條目里时),那么这种工作更适合让机器人而不是人类来进行。

製作机器人前先仔细想好 编辑

维基百科中已经有一些机器人正在运行。其中许多机器人开放了源代码,以便于在某些情况下使用这些源代码缩短新机器人的开发时间。另外,维基百科还有对所有用户开放使用的一些半机器人英语Wikipedia:Semi-bots。它们之中的大多数是拥有维基相关特殊功能的加强浏览器。其中最常使用的便是自动维基浏览器。请参见维基百科:维基百科工具以获得完整列表。

如果你没有先前的编程经验,更简单的办法是请求一个已有的机器人来完成你的工作,或者请求其他人为你编写一个机器人。这类请求可以在Wikipedia:机器人/作业请求中提出。如果你一定要自己编写一个机器人,一定记住学习一门程序语言并不是一个简单的任务。无论如何,这并不是黑魔法-只要花费足够的时间和努力,任何人都可以学会如何编程,祝你好运!

如果你决定去创建一个机器人,那么创建一个无错误、高效且有用的机器人是非常重要的。下面的初步考虑是重要的:

  • 这个机器人将会是人工辅助的还是全自动的?
  • 你会独自一个人创建一个机器人,还是利用其他编程者的帮助?
  • 你将使用什么程序语言来开发这个机器人?
  • 这个机器人的请求,编辑,或是其它行为会不会被记录?如果是,那么这些记录是存储在本地,还是维基页面上?
  • 这个机器人是运行于浏览器之中(比如,用JavaScript编写),或者是一个独立的程序?
  • 如果是一个独立程序,这个机器人将会在你的电脑本地运行,还是在一个类似维基媒体工具服务器的远程服务器上运行?
  • 如果是在远程服务器上运行,其他的编者是否能启动或操作这个机器人?

维基机器人的工作原理 编辑

概论 编辑

 

就像人类编辑者一样,一个维基百科机器人阅读维基百科上的页面,对它认为需要做出变化的地方进行改变。不同之处在于尽管机器人更快并且不会像人类一样容易疲倦,他们并不像我们一样聪明。机器人适用于固定模式的、不需作出决策的重复工作。

在最典型的情况下,机器人登入它自己的帐号并像一个浏览器一样请求维基百科的页面。它不会在显示屏上显示页面,而是在内存中工作。接下来它会程序化地分析页面代码以确定是否需要作出改变。然后它会再次像一个浏览器一样做出它被设计做出的改动并提交更改。

因为机器人以与普通人相同的方式访问页面,它们会体验到和人类用户一样的困难。他们会卷入编辑冲突,遇到页面延迟,或者遇到其它请求或编辑页面时可能遇到的并发错误。因为机器人的工作量远远大于一个普通的人,它们更容易遇到这些问题。因此,当编写一个机器人时,对这些情况的考虑是必要的。

用API寫机器人 编辑

为了对维基百科页面作出更改,机器人有必要从维基百科检索页面并且提交编辑。一些应用程序接口可以被用于这个目的。

  • MediaWiki APIs (api.php)。该库用于制作自动处理查询和提交更改的机器人。可以接受多种机器可读的格式如JSONXMLYAML等。其特性在旧版的查询API接口可以找到,参见API手册
状态:在所有维基媒体项目中可用,包含很全的查询集。通过api.php编辑页面适用于所有维基媒体项目,这允许机器人在没有屏幕抓取英语Screen scraping的情况下工作。
  • 屏幕抓取英语Screen scraping (index.php)。屏幕抓取用于请求维基页面,查看HTML源代码(和你在大多数浏览器中点击查看-页面源代码所看到的一样),之后分析HTML的特性。许多问题可能会在其中发生:维基百科界面可以在毫无提示的情况下改变,这可能会破坏机器人的代码,获取HTML的请求对处理维基文本本身对服务器的压力也更大。当你请求一个页面的精简版本(无维基侧边栏和标签栏)以减少数据传输并减小用户界面更改的影响时,你可以包含代码action=render GET请求 w/index.php?title=Wikipedia:...&action=render 。index.php的其他参数也可能会有帮助:参见列表index.php参数手册。在API有如此多特性的情况下,几乎没有理由再使用这种技术了,这种技术主要用于较古老的机器人框架。
状态: 不鼓励使用。
状态: MediaWiki的内置特性,在所有维基媒体服务器上均能使用。
  • 原生(维基文本)页面处理。使用action=rawaction=raw&templates=expand GET请求到index.php可以获取一个页面未处理过的维基文本源码。带有prop=revisions&rvprop=contentprop=revisions&rvprop=content&rvexpandtemplates=1的API查询也大致做类似的工作,同时允许检索一些附加信息。
状态: MediaWiki的内置特性,在所有维基媒体服务器上均能使用。

一些维基百科服务器为大规模数据获取配置了压缩(gzip内容。这可以通过在HTTP请求头里加上一行"Accept-Encoding: gzip"来获得。如果HTTP回报头包含"Content-Encoding: gzip"就表明文档是gzip格式的,否则为普通的未压缩格式。注意这些特性仅仅是对于特定的服务器而配置的,并不是MediaWiki软件的特性。其他部署MediaWiki的网站可能没有此特性。

登入/建立新帳號 编辑

被认可的机器人需要登录以作出编辑。尽管机器人可以在没有登录的情况下作出读取请求,完成测试的机器人还是应该登录以进行所有活动。登录拥有机器人标签的账号的机器人可以在每次对Mediawiki API(api.php)请求时获得更多结果。大多数机器人程序框架应该自动处理登录以及Cookies,但是如果你没有使用一个存在的框架,你需要进行以下步骤。

为了安全起见,登录数据必须使用HTTP POST方式传送。因为HTTP GET请求的参数在URL中很容易看见,通过GET登录是禁止的。

为了使用MediaWiki API登录一个机器人,需要两个POST请求:

请求1

如果密码正确,会返回一个“NeedToken”的结果和一个XML格式的“标记”参数,参见文档mw:API:Login。其他输出格式是可用的。它也会返回如下所示的HTTP Cookie。

请求2

其中TOKEN是上一步结果获得的令牌。上一步请求获得的HTTP cookies必须与第二个请求一起传入。

BOTPASSWORD是使用Special:BotPasswords取得的密碼,而不是登入帳號取得的密碼。

一个成功的登录尝试会从维基媒体服务器得到几个HTTP cookie。机器人必须正确处理这些cookies并且在每次请求时发送回去(在编辑时更加重要)。在中文维基百科里会使用以下cookies:zhwikiUserIDzhwikiTokenzhwikiUserNamezhwikisession缓存在发送或确认编辑时需要,否则会返回一个错误信息

编辑;编辑令牌 编辑

在编辑维基百科的页面时,需使用编辑令牌系统。这个令牌看上去像一个末尾有“+\”的长十六进制数,例如:

d41d8cd98f00b204e9800998ecf8427e+\

编辑令牌的作用是防止“编辑劫持”(这种情况下,编辑者无意点击某链接就可能产生编辑操作)

编辑过程涉及到两个HTTP请求。第一步请求一个编辑令牌,第二步把要编辑页面的新内容和刚才获得的编辑令牌放在一起进行POST请求。每次登录后编辑令牌都不会改变,因此第一步每次登录只需做一次。[來源請求]

要获得一个编辑令牌,请按照下列步骤做:

  • 用以下参数向MediaWiki API (api.php)发出POST请求(参见 mw:API:Edit):
    • action=query
    • meta=tokens
    • type=csrf

    令牌一定会在返回值的csrftoken属性中。

如果机器人获取到的编辑令牌没有上述的十六位字符串(如编辑令牌只有'+\'),则说明机器人很可能没有成功登录。这可能有多种原因:服务器端身份验证失败、连接断开或超时、cookies存储/返回错误。如果这不是因为机器人程序错误,再次登录以刷新登录缓存即可。机器人可以使用Assert Api来确认其已经登录。

编辑冲突 编辑

当多人同时尝试编辑一个页面时会发生编辑冲突。几乎每个机器人都会遇到各种各样的编辑冲突,因此制作机器人时应当包括处理编辑冲突的机制。

使用Mediawiki API(api.php)的机器人在读取页面准备编辑前,应当重新获取编辑令牌以及starttimestamp(开始时间戳)和上一个版本的时间戳。可以使用prop=info|revisions在一次查询中同时获取令牌和页面的内容(example)。当提交编辑时,设置starttimestampbasetimestamp属性,并检查服务器回应是否有错误信息。更多的细节,请参见mw:API:Edit - Create&Edit pages

总的来说,如果一次编辑没有完成,机器人应当在做新编辑前再次检查页面,以确定编辑仍然是正确的。进一步说,如果机器人重新检查并提交编辑,它必须足够小心以避免可能导致的无限循环甚至编辑战

机器人制作过程概览 编辑

实际上,撰写机器人代码只是制作维基百科机器人工作的一部分。机器人操作者应该大致仿照以下开发步骤以保证机器人遵循维基百科的机器人方针。违背方针的机器人无法得到审批,严重者甚至会被封禁。

 
维基百科机器人开发流程概览

构思 编辑

细化 编辑

  • 精确地(可能用一种非常严格的方式)描述你要写的软件有什么任务要做。你应该详尽地提出它要做什么事。尝试和其他的编辑者讨论这个提议,并基于其他人的反馈来进行改进。即使是一个很伟大的想法,也能通过综合其他编辑者的想法而变得更好。
  • 在最基本的情况下,经过你细化之后的机器人必须符合下列标准:
  • 无害(机器人的编辑不能对维基百科的平稳运行造成破坏)
  • 有用(机器人能够比人工编辑更有效率,提供有用的服务)
  • 不浪费服务器资源
  • 遵守模板:Bots

软件架构 编辑

  • 想一想你要怎么造这个机器人,用什么样的编程语言和工具。一般认为,使用软件架构能确保让软件系统符合产品需求,并且能确保迎合未来的需求。一些编程语言比另一些更适合做某些任务,更多细节请参考#编程语言和开发库

实现 编辑

实现(编码)涉及到把设计和计划转变成代码。这可能是软件工程里面最显而易见的工作了,但是并没必要成为最大的一部分工作。在实现阶段,你需要做:

  • 给你的机器人建立一个用户页。机器人绝对不能使用你自己的账号进行编辑。机器人需要它自己的账号,有自己的用户名和密码。
  • 在机器人的用户页上加入相同信息。加上一个指向讨论页面的链接是个不错的想法,大家可以对每一个功能提出赞成或者反对的意见。
  • 用你选择的编程语言对机器人编写代码。

测试 编辑

测试你的机器人最好的方式是:让它把要进行的更改写在一个页面上,而不是对维基进行实际的更改。有的机器人框架(比如Pywikipediabot)有一些现成的方法可以用来显示差异。在申请期间,机器人很可能会有一个试用期(有一些编辑次数或者运行时间上的限制),在此期间让它进行一些实际的编辑,便于对它进行微调、解决Bug。试用期结束的时候,如果一切都按照计划进行,机器人就应该能被批准执行全功能的操作。

文档 编辑

一个重要的(也是常常被忽视的)任务就是为机器人的内部设计撰写文档,这样是为了便于将来的维护和增强。如果你允许复制你的机器人的话,这就尤其重要了。如果你想让别人可以复制你的机器人,最理想的情况是在它的用户页上公布源代码。为了便于使用,代码应该有详细的文档说明(通常使用注释)。

询问和抱怨 编辑

你应该准备好在你的对话页上回应对机器人的各种询问或反对意见,尤其是在机器人在一个潜在的敏感区域进行操作(比如清理合理使用图像)的情况下。

维护 编辑

为了解决发现的Bug,或者迎合新的需求,维护和改进机器人会比一开始开发的时候花费的时间多得多。不光是加入与原始设计不相符的代码,仅仅就是确定软件维护完成之后在某些点上怎么工作,就需要很大的努力(这也是一直要为代码写文档的一个原因)。

  • 如果你要对机器人在功能上做一个重大的修改,应该提出申请

运行机器人的一般准则 编辑

官方的机器人政策给出了开发机器人的时候应该考虑的一些主要问题。除此之外,还有一些更一般的问题应该考虑。

编写机器人的最佳做法 编辑

  • 按照维基媒体用户代理政策,为机器人设置一个用户代理头。如果不这样做的话,机器人可能会遇到错误,最终可能会被技术人员在服务器级别进行屏蔽。
  • 使用5秒的最大延迟参数。这能让机器人在服务器负载低的时候快速运行,在服务器负载高的时候暂停运行。
    • 如果编写机器人使用的框架不支持最大延迟的话,请限制总请求数(包括读写请求),不要超过每秒10次。
  • 尽可能地使用API,把查询频率限制到服务器允许的最大值,把总请求数设置为足够小的值。
  • 编辑(写)请求比读请求更耗费服务器时间。设计代码的时候,把编辑操作控制到最少。
    • 尽量整合多次编辑。一次大编辑要好过十次小编辑。
  • 如果可以的话,在HTTP客户端库里启用HTTP持久链接HTTP压缩
  • 不要用多线程发出请求。等到一次请求完成之后再开始下一次请求。
  • 当从服务器收到错误信息的时候,使用二元指數後退演算法(Binary Exponential Backoff Algorithm) 进行延迟。像超时这样的错误常常意味着服务器负载过重。在重复发出的请求之间采用递增的时间延迟。
  • 使用断言编辑扩展。这是一个专门为机器人设计的扩展,用来检查特定的条件是否成立。这个扩展已经在维基百科上启用了。
  • 在开始大型的自动化运行前,彻底测试好你的代码。逐个考察试运行期间所有的编辑操作,确保完美。

应该考虑实现的常见机器人特征 编辑

人工协助 编辑

如果机器人所做的工作需要根据上下文进行判断或评价(例如改正拼写错误),你应该考虑让你的机器人可以人工协助。也就是说,别让机器人的编辑没有人工确认。

停用机器人 编辑

好的机器人应该可以在有必要的时候停用。请记住,如果你的机器人出错了,你有责任对这些错误进行清理!你应该让机器人在看到对话页上留有特定信息的时候拒绝运行。这个信息可能是对它的活动抱怨的信息;这个可以用API meta=userinfo 查询(这里有个例子)。或者,你可以设置一个页面,如果这个页面的内容被改动,机器人就会停止运行(例如,机器人需要这个页面是空的,仅仅有一个词“True”或者其他什么东西才能运行);可以在每次编辑之前载入这个页面,检查页面的内容。

签名 编辑

就像人一样,如果机器人要编辑维基百科的讨论页,他也应该用四个波浪线(~~~~)留下签名。请记住,签名应该留在讨论页(talk命名空间)上,不要让机器人在任何其他的页面上签名。

开源机器人 编辑

许多操作机器人的人选择开放源代码,在有些情况下,申请特定的复杂机器人之前可能会要求开源。开放你的代码有几个好处:

  • 允许别人再审查一下你的代码,发现潜在的Bug。As with prose,对于代码的作者来说,完全复审代码经常是件困难的事。
  • 别人可以使用你的代码制作他们自己的机器人。可以让一个刚开始写机器人的用户在写机器人的时候,能拿你的代码做例子或者模板。
  • 鼓励更安全的做法,而不是“隐藏就是安全”(“security through obscurity”)。
  • 如果你离开这个项目了,允许其他用户不用写新代码就可以运行你的机器人。

虽然开源代码很少需要,有些情况下代码也不应该公开(例如英文维基百科中,机器人ProcseeBot的开源代码中含有寻找代理的代码,就可以被其他网站用于恶意目的),但是维基百科鼓励开源,因为维基百科要保持开放和透明的性质。

开放源代码可能为编写代码带来额外的工作。要确保把像密码这样的敏感信息分开保存在不公开的文件里。

开放源代码有几种不同的选择。有的用户可能选择把代码放在机器人用户空间的一个子页面上,虽然这样会带来维护上麻烦(如果不是自动的话),而且会使代码在多个协议(维基百科的协议再加上你自己指定的协议)下发布。另一种解决方案是使用版本控制系统,比如SVNGitMercurial。英文维基百科上有两个条目,一个是比较不同的版本控制系统之间的区别,另一个比较不同开源软件托管设备间的区别(目前(2012年1月19日)中文维基百科也有一个条目对应后者:自由软件主机服务比较),其中很多是免费的。维基媒体工具服务(Wikimedia Toolserver)也为用户提供SVN托管服务

编程语言和开发库 编辑

几乎任何编程语言都可以编写机器人。选择什么样的语言常常取决于机器人编写者的经验(哪种语言比较熟悉),或者是哪种预先开发的库更适合于完成所需的任务。下面列出了一些语言,它们有一些开发库,用来协助完成机器人的任务。

Perl 编辑

Perl运行时编译器。这就意味着不需要像其他语言那样自己编译每一次构建(Build)。相反,你只需要简单地使用像Gvim这样的文本编辑器就能创建程序。然后,把代码交给解释器执行。代码不是位于你自己的电脑上,就是位于远程电脑(Web服务器)上。如果位于Web服务器上,你可以通过CGI开始运行程序,启动接口服务。Perl适用于大多数操作系统,包括Microsoft WindowsMac OS XUNIX/Linux。如果你的ISP提供给你Web空间,那么这是个好机会,你可以在Web服务器上访问、运行Perl程序。

Perl编程入门指南:

开发库:

  • MediaWiki::API – 一个Perl模块,基于MediaWiki API提供低级接口,允许检索、编辑、上传/下载文件。
  • MediaWiki::Bot – 一个相当完整的机器人架构,用Perl写成。提供比MediaWiki::API更高级的抽象。插件可提供管理功能。
  • Anura – 使用libwww-perl的,到MediaWiki的Perl接口。不推荐使用,因为当前版本不会检查编辑冲突。
  • WWW::Mediawiki::Client – Perl模块和命令行客户端。
  • WWW::Wikipedia – Perl模块,提供维基百科接口。
  • Perl Wikipedia ToolKit – Perl模块,解析维基格式文本,提取数据。
  • MediaWiki CPAN Package[失效連結] by Edward Chernenko – 丰富的API,但是也有几个严重的Bug。
  • Mediawiki::API – 英文维基百科用户CBM编写的开发库,具有强大的自动错误处理功能,包装了许多常见的API.php使用方式。这个开发库与CPAN上的开发库不同。

PHP 编辑

PHP可以用于编写机器人。如果你想对机器人提供基于Web表单的接口,那么PHP是特别好的选择(尤其是使用cURL拓展,可以实现基于HTTP/HTTPS的请求)。举个例子,假如你想创建一个用于重命名分类的机器人,你可以创建一个HTML表单,把分类的当前和所需名称填到表单里。当表单提交的时候,机器人可以读取这些输入,然后编辑当前分类下的所有文章,把它们移动到所需的分类。(很显然,使用表单接口的机器人与在Web上随机冲浪的机器人相比,在某种程度上更加安全)

Python 编辑

Python是一种流行的解释型面向对象语言。

Python入门:

开发库:

Microsoft .NET 编辑

Microsoft .NET是一组编程语言,包括C#C++/CLIVisual Basic .NETJ#JScript .NETIronPython,和Windows PowerShell。经常使用的开发环境是Microsoft Visual Studio integrated development environment,或者是其免费版本Microsoft Visual Studio Express。.NET程序使用Mono Project,可以在LinuxUnixBSDSolarisMac OS X,以及Windows上运行。

入门:

Libraries:

Java 编辑

Java程序一般使用IDE开发,比如Eclipse;也可以使用命令行控制台开发(使用javac和其他Java程序)。

入门:

开发库:

JavaScript 编辑

JavaScript是一种主要用于网页的脚本语言。通过把JavaScript脚本添加到your vector.js或者your monobook.js,可以增强维基百科的功能。在某些情况下,JavaScript脚本也可能离线执行。

开发库:

  • 英文维基百科上的机器人Luasóg bot是一个JavaScript框架,可用于标准的请求(例如登录、退出、读取、编辑等等),也有对MediaWiki API的一般包装方法,还包含了像节流这样那个的有用的东西。这个项目包含了一个低级的IDE,可用于离线开发和执行。
  • Cewbot 採用了包含製作機器人功能的 JavaScript 軟體架構,可離線開發和運行。
framework: wikiapi / CeJS MediaWiki 自動化作業用的程式庫
可執行環境: node.js, JScript
採用 CeJS 函式庫來製作維基百科機器人的範例

Ruby 编辑

开发库:

  • MediaWiki::Gateway – API的Ruby框架。已积极地维护、测试到了MediaWiki 1.16,与维基媒体的诸站点兼容。
  • rbmediawiki – 用Ruby编写机器人的框架,使用MediaWiki的API。作者是英文维基百科用户Ignacio Icke

Chicken Scheme 编辑

Iron Chicken是Chicken Scheme的扩展,使Mediawiki API可以用S-表达式编写,提供API和SXML格式的HTML输出,可以很容易地查询。

示例:获取一个分类的成员,写入一个客户端用户的用户空间页面:

开发库:

Common Lisp 编辑

  • cl-mediawiki是实现了MediaWikiAPI的Common Lisp包。使用JSON作为查询数据格式。支持最大延迟和断言编辑扩展。

Haskell 编辑

Tcl 编辑

C++/Qt4.5 编辑

  • [1](俄文) – 简单的维基媒体机器人,用C++/Qt写成,只有很少的功能,像认证、获取页面源码、提交页面源码。