40

我尝试使用 Python 的 urllib 获取 Wikipedia 文章:

f = urllib.urlopen("http://en.wikipedia.org/w/index.php?title=Albert_Einstein&printable=yes")           
s = f.read()
f.close()

但是,我得到以下响应,而不是 html 页面:错误 - 维基媒体基金会:

Request: GET http://en.wikipedia.org/w/index.php?title=Albert_Einstein&printable=yes, from 192.35.17.11 via knsq1.knams.wikimedia.org (squid/2.6.STABLE21) to ()
Error: ERR_ACCESS_DENIED, errno [No Error] at Tue, 23 Sep 2008 09:09:08 GMT 

维基百科似乎阻止了不是来自标准浏览器的请求。

有人知道如何解决这个问题吗?

4

10 回答 10

50

您需要在python std 库中使用替代urllib的urllib2来更改用户代理。

直接从例子

import urllib2
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
infile = opener.open('http://en.wikipedia.org/w/index.php?title=Albert_Einstein&printable=yes')
page = infile.read()
于 2008-09-23T09:50:39.893 回答
36

它不是针对特定问题的解决方案。但您可能会感兴趣的是使用 mwclient 库 ( http://botwiki.sno.cc/wiki/Python:Mwclient )。那会容易得多。特别是因为您将直接获取文章内容,从而无需解析 html。

我自己在两个项目中使用过它,效果很好。

于 2008-09-23T09:49:44.763 回答
15

与其试图欺骗 Wikipedia,不如考虑使用他们的High-Level API

于 2009-06-11T11:14:20.137 回答
3

如果您尝试访问 Wikipedia 内容(并且不需要有关页面本身的任何特定信息),您应该只使用 'action=raw' 调用 index.php 来获取 wikitext,而不是使用 api,例如在:

'http://en.wikipedia.org/w/index.php? 动作=原始&title=Main_Page'

或者,如果您想要 HTML 代码,请使用 'action=render',如下所示:

'http://en.wikipedia.org/w/index.php? 动作=渲染&title=Main_Page'

您还可以定义一个部分来获取部分内容,例如“section=3”。

然后,您可以使用 urllib2 模块访问它(如所选答案中所建议的那样)。但是,如果您需要有关页面本身的信息(例如修订),您最好使用上面建议的 mwclient。

如果您需要更多信息,请参阅MediaWiki 的常见问题解答。

于 2010-11-12T19:16:55.070 回答
2

我用于任何站点的一般解决方案是使用 Firefox 访问该页面,并使用 Firebug 等扩展程序记录 HTTP 请求的所有详细信息,包括任何 cookie。

在您的程序中(在本例中为 Python),您应该尝试发送一个与 Firefox 类似的 HTTP 请求。这通常包括设置 User-Agent、Referer 和 Cookie 字段,但可能还有其他字段。

于 2008-09-23T09:51:31.560 回答
2

requests太棒了!

以下是获取 html 内容的方法requests

import requests
html = requests.get('http://en.wikipedia.org/w/index.php?title=Albert_Einstein&printable=yes').text

完毕!

于 2014-09-19T05:37:15.860 回答
1

尝试将您在请求中发送的用户代理标头更改为: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008072820 Ubuntu/8.04 (hardy)火狐/3.0.1 (Linux Mint)

于 2008-09-23T09:41:22.240 回答
1

您不需要模拟浏览器用户代理;任何用户代理都可以工作,而不是空白的。

于 2008-09-23T09:48:05.610 回答
1

请求页面?printable=yes为您提供了一个完整的相对干净的 HTML 文档。?action=render只为您提供正文 HTML。请求通过 MediaWiki 操作 API 解析页面action=parse同样只为您提供正文 HTML,但如果您想要更好的控制,请参阅 parse API 帮助

如果您只想要页面 HTML 以便可以呈现它,那么使用新的RESTBase API 会更快更好,它会返回页面的缓存 HTML 表示。在这种情况下,https://en.wikipedia.org/api/rest_v1/page/html/Albert_Einstein

自 2015 年 11 月起,您不必设置用户代理,但强烈建议您这样做。此外,几乎所有 Wikimedia wiki都需要 HTTPS,因此请避免 301 重定向并发出 http请求

于 2015-11-11T05:56:24.040 回答
0
import urllib
s = urllib.urlopen('http://en.wikipedia.org/w/index.php?action=raw&title=Albert_Einstein').read()

这似乎对我有用,而无需更改用户代理。没有“action=raw”,它对我不起作用。

于 2011-01-25T15:02:18.943 回答