4

我只需要为了一个非常特殊的目的查询维基百科,即获取给定 url 的文本。更准确地说:

我有大约 14.000 个英文语料库的维基百科 url,我需要获取文本,或者至少需要这些 url 的介绍。我的进一步处理将在 python 中,所以这将是选择的语言。

我正在寻找性能最佳的方法,并组成了 4 种不同的方法:

  1. 直接通过python获取xml转储和解析
    ->这里的进一步问题是:如何查询xml文件,知道url?
  2. 获取xml,设置数据库并sql使用python查询
    ->这里的进一步问题是:如何查询sql,知道url?
  3. 使用wikipedia api并通过python直接查询
  4. 只需抓取这些维基百科页面(这可能有点偷偷摸摸,也很烦人,因为它的 html 并且没有纯文本)

我应该使用哪种方法,即哪种方法具有最佳性能并且在某种程度上是标准的?

4

2 回答 2

8

一些想法:

我有大约 14.000 个英文语料库的维基百科 url,我需要获取文本,或者至少需要这些 url 的介绍。

1 - 直接通过 python 获取 xml 转储和解析

英文维基百科目前有 4,140,​​640 篇文章。您对 14,000 篇文章感兴趣,约占总数的三分之一。这听起来太稀疏了,不能让倾倒所有文章成为最好的方法。

2 - 获取xml,设置数据库并使用python查询sql

您希望您感兴趣的文章集增长或改变吗?如果您需要快速响应文章集中的变化,本地数据库可能会很有用。但你必须保持最新。如果速度足够快,使用 API 获取实时数据会更简单。

4 - 只需抓取这些维基百科页面(这可能有点偷偷摸摸,也很烦人,因为它的 html 并且没有纯文本)

如果你能从 API 中得到你需要的东西,那将比爬取维基百科站点更好。

3 - 使用wikipedia api并通过python直接查询

根据您感兴趣的文章的低百分比(0.338%),这可能是最好的方法。

请务必查看MediaWiki API 文档API 参考。还有python-wikitools 模块

我需要得到文本,或者至少是介绍

如果您真的只需要介绍,那将节省大量流量,并且确实使使用 API 成为迄今为止的最佳选择。

检索引言的方法有很多种,这里有一个好方法:

http://en.wikipedia.org/w/api.php?action=query&prop=extracts&exintro&format=xml&titles=Python_(programming_language)

如果您一次处理多个请求,您可以将它们分成最多 20 篇文章的组:

http://en.wikipedia.org/w/api.php?action=query&prop=extracts&exintro&exlimit=20&format=xml&titles=Python_(programming_language)|History_of_Python|Guido_van_Rossum

这样,您可以在 700 次往返中检索 14,000 篇文章介绍。

注意: API 参考 exlimit文档指出:

不超过 20 个(机器人为 20 个)

另请注意: 关于礼仪和使用限制的 API 文档部分说:

如果您以串行方式而不是并行方式发出请求(即在发送新请求之前等待一个请求完成,这样您就不会同时发出多个请求),那么您肯定没问题。还可以尝试将事物组合到一个请求中(例如,在标题参数中使用多个标题,而不是为每个标题发出新请求。

维基百科不断更新。如果您需要刷新数据,跟踪修订 ID 和时间戳将使您能够识别哪些本地文章是过时的。您可以使用(例如)检索修订信息(连同介绍,这里有多篇文章):

http://en.wikipedia.org/w/api.php?action=query&prop=revisions|extracts&exintro&exlimit=20&rvprop=ids|timestamp&format=xml&titles=Python_(programming_language)|History_of_Python|Guido_van_Rossum

于 2013-01-10T14:21:21.580 回答
0

这也只是答案的一部分,我对 jimhark 提出的一种可能的解决方案做了一些自我介绍:

维基百科 API

我使用了这段代码,保存在query.py

import urllib2
import xml.etree.ElementTree as ET
import numpy as np

for i in np.arange(0,1000):
    url = 'http://en.wikipedia.org/w/api.php?format=xml&action=query&titles=Fish&prop=revisions&rvprop=content'
    response = urllib2.urlopen(url)
    html_string = response.read()
    a = ET.fromstring(html_string)
    try :
        a.find('query').find('pages').find('page').find('revisions').find('rev').text
    except (AttributeError):
        pass

跑了python -m cProfile query.py

这不是很聪明的分析,因为很可能 Wikipeda api 会将查询缓存到fish.

结果:

1431056 function calls (1412734 primitive calls) in 686.813 seconds

几乎所有的地方,因为:

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
118081  644.566    0.005  644.566    0.005 {method 'recv' of '_socket.socket' objects}

我将尝试将其用于我的数据集并让您知道。

于 2013-01-10T15:21:58.713 回答