【问题标题】:Error crawling wikipedia抓取维基百科时出错
【发布时间】:2026-01-29 11:30:01
【问题描述】:

根据@Jens Timmerman 在这篇文章中的回答:Extract the first paragraph from a Wikipedia article (Python)

我这样做了:

import urllib2
def getPage(url):
    opener = urllib2.build_opener()
    opener.addheaders = [('User-agent', 'Mozilla/5.0')] #wikipedia needs this

    resource = opener.open("http://en.wikipedia.org/wiki/" + url)
    data = resource.read()
    resource.close()
    return data

print getPage('Steve_Jobs')

从技术上讲,它应该可以正常运行并给我页面的来源。但这是我得到的:

任何帮助将不胜感激..

【问题讨论】:

  • 如果可以使用他们的API,为什么还要爬*?
  • @NullUserException,很抱歉,但我讨厌像你这样的 cmets。 OP 想使用python 来实现,我们能否只专注于帮助他实现这一目标而不是建议替代方法?
  • @l19: NullUserException 完全正确; Wikipedia API 可以从 Python 中使用(实际上,这是最常见的场景之一),因为它们只是简单的 HTTP 请求,就像我们现在讨论的那样。不同之处在于它们通常更灵活,并且返回的数据通常是机器可读的格式,这对于我们的脚本来说通常是一个很大的优势,不需要浪费时间呈现 MediaWiki 标记。
  • @l19 API 专门为此目的而设计,因此您不必抓取网站。正如 Matteo 所说,这对*你都有好处。实际上,一些网站明确禁止您抓取它们,同时允许您通过 API 访问。我不认为*是其中之一,但他们的robots.txt 表明他们并不是很喜欢爬行。如果您正在访问某人的应用程序,请尊重开发人员的意愿,并通过 API 按他们希望的方式进行操作。

标签: python


【解决方案1】:

在检查了wgetcurl 之后,我发现这不是Python 特有的问题——它们也有“奇怪”的字符;对file 的快速检查告诉我,响应只是经过 gzip 压缩,所以似乎 Wikipedia 默认只发送 gzip 压缩的数据,而不检查客户端是否真的在请求中表示支持它。

幸运的是,Python 能够解压缩 gzip 压缩的数据:将您的代码与 this answer 集成,您将获得:

import urllib2
from StringIO import StringIO
import gzip

def getPage(url):
    opener = urllib2.build_opener()
    opener.addheaders = [('User-agent', 'MyTestScript/1.0 (contact at myscript@mysite.com)'), ('Accept-encoding', 'gzip')]
    resource = opener.open("http://en.wikipedia.org/wiki/" + url)
    if resource.info().get('Content-Encoding') == 'gzip':
        buf = StringIO( resource.read())
        f = gzip.GzipFile(fileobj=buf)
        return f.read()
    else:
        return resource.read()

print getPage('Steve_Jobs')

这在我的机器上运行良好。

不过,正如 cmets 中已经指出的那样,如果您想以编程方式使用其 API 访问 Wikipedia 内容,您可能应该避免“野蛮爬行”。

【讨论】: