3

我无法让我的机器人登录到 Intranet 上的 MediaWiki 安装。我相信这是由于 http 身份验证保护了 wiki。

事实:

  1. wiki 根目录是:https ://local.example.com/mywiki/
  2. 使用 Web 浏览器访问 wiki 时,会弹出一个要求提供企业凭据的弹出窗口(我假设这是基本访问身份验证)

这就是我的 user-config.py 中的内容:

mylang = 'en'
family = 'mywiki'
usernames['mywiki']['en'] = u'Bot'
authenticate['local.example.com'] = ('user', 'pass')

这就是我在 mywiki_family.py 中的内容:

# -*- coding: utf-8  -*-
import family, config

# The Wikimedia family that is known as mywiki
class Family(family.Family):
  def __init__(self):
      family.Family.__init__(self)
      self.name = 'mywiki'
      self.langs = { 'en' : 'local.example.com'}

  def scriptpath(self, code):
      return '/mywiki'

  def version(self, code):
      return '1.13.5'

  def isPublic(self):
      return False

  def hostname(self, code):
      return 'local.example.com'

  def protocol(self, code):
      return 'https'

  def path(self, code):
      return '/mywiki/index.php'

当我执行 login.py -v -v 时,我得到这个:

urllib2.urlopen(urllib2.Request('https://local.example.com/w/index.php?title=Special:Userlogin&useskin=monobook&action=submit', wpSkipCookieCheck=1&wpPassword=XXXX&wpDomain=&wpRemember=1&wpLoginattempt=Aanmelden%20%26%20Inschrijven&wpName=Bot, {'Content-type': 'application/x-www-form-urlencoded', 'User-agent': 'PythonWikipediaBot/1.0'})):
(Redundant traceback info here)
urllib2.HTTPError: HTTP Error 401: Unauthorized

(我不确定为什么它有 'local.example.com/w' 而不是 '/mywiki'。)

我认为它可能正在尝试对 example.com 而不是 example.com/wiki 进行身份验证,因此我将身份验证行更改为:

authenticate['local.example.com/mywiki'] = ('user', 'pass')

但后来我从 IIS 收到 HTTP 401.2 错误:

您无权使用您提供的凭据查看此目录或页面,因为您的 Web 浏览器正在发送 Web 服务器未配置为接受的 WWW-Authenticate 标头字段。

任何有关如何使这项工作的帮助将不胜感激。

更新修复我的家庭档案后,它现在说:

获取站点 mywiki:en 的信息('http 错误'、401、'未授权'、)警告:无法打开' https://local.example.com/mywiki/index.php?title=Non-existing_page&action=edit&useskin=单书'. 也许服务器或您的连接已关闭。1 分钟后重试...

我查看了计划 urllib2.ulropen 调用中的 HTTP 标头,它使用的是 WWW-Authenticate: Negotiate WWW-Authenticate: NTLM。我猜是 urllib2,因此 pywikipedia 不支持这个?

更新添加了一个美味的赏金以帮助使其正常工作。我可以使用 python-ntlm 进行身份验证。如何将其集成到 pywikipedia 中?

4

2 回答 2

4

好吧,login.py尝试访问 '\w' 而不是您的路径这一事实表明存在家庭配置问题。

您的代码缩进很奇怪:是scriptpath新 Family 类的成员吗?如:

class Family(family.Family):
    def __init__(self):
        family.Family.__init__(self)
        self.name = 'mywiki'
        self.langs = { 'en' : 'local.example.com'}

    def scriptpath(self, code):
        return '/mywiki'

    def version(self, code):
        return '1.13.5'

    def isPublic(self):
        return False

    def hostname(self, code):
        return 'local.example.com'

    def protocol(self, code):
        return 'https'

?

我相信你的家庭档案有问题。检查的一个好方法是在 python 控制台中进行:

import wikipedia
site = wikipedia.getSite('en', 'mywiki')
print site.login_address()

只要相对地址有误,显示'/w'而不是'/mywiki',就说明family文件还没有正确配置,bot不能工作:)

更新:如何在 pywikipedia 中集成 ntlm?

我只是看了一下这里的基本示例。我会将该行之前的代码集成到login.py

response = urllib2.urlopen(urllib2.Request(self.site.protocol() + '://' + self.site.hostname() + address, data, headers))

你想写类似的东西:

from ntlm import HTTPNtlmAuthHandler

user = 'DOMAIN\User'
password = "Password"
url = self.site.protocol() + '://' + self.site.hostname()

passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, url, user, password)
# create the NTLM authentication handler
auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman)

# create and install the opener
opener = urllib2.build_opener(auth_NTLM)
urllib2.install_opener(opener)

response = urllib2.urlopen(urllib2.Request(self.site.protocol() + '://' + self.site.hostname() + address, data, headers))

如果我有可用的 ntlm 设置,我会对此进行测试并将其直接集成到 pywikipedia 代码库中......

无论发生什么,请不要随您的解决方案消失:在 pywikipedia,我们对您的解决方案很感兴趣 :)

于 2009-08-11T07:29:46.580 回答
0

我猜您遇到的问题是服务器需要基本身份验证,而您没有在客户端处理它。Michael Foord 写了一篇关于在 Python 中处理基本身份验证的好文章。

你没有提供足够的信息让我确定这一点,所以如果这不起作用,请提供一些额外的信息,比如你连接尝试的网络转储。

于 2009-08-10T22:31:59.273 回答