使用Python获取Wikipedia文章
我尝试使用Python的urllib来获取Wikipedia文章:
f = urllib.urlopen("http://en.wikipedia.org/w/index.php?title=Albert_Einstein&printable=yes") s = f.read() f.close()
但是,我得到的不是HTML页面,而是以下响应:错误Wikimedia Foundation:
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
维基百科似乎阻止了不是来自标准浏览器的请求。
有人知道如何解决这个问题吗?
解决方案
尝试将请求中发送的用户代理标头更改为以下内容:
用户代理:Mozilla / 5.0(X11; U; Linux i686; zh-CN; rv:1.9.0.1)Gecko / 2008072820 Ubuntu / 8.04(hardy)Firefox / 3.0.1(Linux Mint)
我们无需模拟浏览器用户代理;完全没有任何用户代理都可以使用,只是没有空白。
这不是解决特定问题的方法。但是使用mwclient库(http://botwiki.sno.cc/wiki/Python:Mwclient)可能对我们来说很有趣。那会容易得多。特别是因为我们将直接获得文章内容,因此无需解析html。
我已经将它用于两个项目,并且效果很好。
我们需要使用替代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()
我在任何站点上使用的通用解决方案是使用Firefox访问该页面,并使用Firebug等扩展程序记录HTTP请求的所有详细信息,包括任何cookie。
在程序中(在本例中为Python),我们应该尝试发送与Firefox正常工作的HTTP请求类似的请求。这通常包括设置User-Agent,Referer和Cookie字段,但是可能还有其他字段。
与其尝试欺骗Wikipedia,不如考虑使用其高级API。
如果我们尝试访问Wikipedia内容(并且不需要有关页面本身的任何特定信息),则不使用api,而应仅使用带有" action = raw"的index.php来获取Wikitext,例如在:
'http://en.wikipedia.org/w/index.php?action=raw&title=Main_Page'
或者,如果我们想要HTML代码,请使用" action = render",如下所示:
'http://en.wikipedia.org/w/index.php?action=render&title=Main_Page'
我们还可以定义一个部分以仅获取部分内容,例如" section = 3"。
然后,我们可以使用urllib2模块(如所选答案中所建议的那样)访问它。
但是,如果我们需要有关页面本身的信息(例如修订),则最好使用上面提到的mwclient。
如果需要更多信息,请参考MediaWiki的FAQ。