在Python和R维基百科哲学游戏图


所以我对python比较陌生,为了学习,我已经开始编写一个程序,可以在线上找到维基百科,在随机文章的概述部分找到第一个链接,跟随该链接并继续前进,直到它进入循环或找到哲学页面(如此处所述),然后重复此过程以获得指定次数的新随机文章。 然后我想以某种形式的有用数据结构收集结果,以便我可以使用Rpy库将数据传递给R,以便我可以绘制某种网络图(R非常擅长绘制类似的东西)图中的每个节点代表所访问的页面,以及从起始文章到哲学页面的路径。

所以我没有问题让python从wiki中返回相当结构化的html,但有一些问题我不明白。 到目前为止,我已经从lxml库中选择了使用cssselector的第一个链接。 它选择作为ap标签的直接后代的第一个链接(在a标签中),即class =“mw-content-ltr”的div标签的直接后代,如下所示:

    user_agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT)'
    values = {'name' : 'David Kavanagh',
      'location' : 'Belfast',
      'language' : 'Python' }
    headers = { 'User-Agent' : user_agent }
    encodes = urllib.urlencode(values)
    req = urllib2.Request(url, encodes, headers)
    page = urllib2.urlopen(req)
    root = parse(page).getroot()
    return root.cssselect("div.mw-content-ltr>p>a")[0].get('href')

此代码驻留在我用来查找页面中第一个链接的函数中。 它的作用大部分,但问题是,如果第一个链接是在一些其他标签内,而不是作为ap标签的直接后代,比如我们说ab标签或其他东西,那么我错过了它。 从上面的wiki文章中可以看到,斜体或圆括号内的链接不符合游戏的条件,这意味着我从来没有得到斜体链接(良好),但经常会获得括号内的链接(错误)和有时会错过页面上的第一个链接,就像椅子上的第一个链接,这是凳子,但它是粗体的,所以我不明白。 我曾尝试删除直接后代规定,但随后我经常会在总览部分“上方”(通常位于侧边框中),ap标签,表格中,与概览部分相同的div中获取链接。

所以我的问题的第一部分是:

如何使用cssselectors或其他函数或库来选择概览部分中不在括号内或斜体内的第一个链接。 我想过使用正则表达式来查看原始html,但这似乎是一个非常笨重的解决方案,我认为可能有一些我没有想到的更好的东西。

所以目前我将结果存储在列表中。 所以我有一个名为paths的列表,其中有一些列表包含了包含wiki文章标题的字符串。

问题的第二部分是:我如何遍历这个列表来表示多个收敛路径? 像这样存储结果是一个好主意吗? 由于末端图应该看起来像是一个颠倒的树,所以我考虑制作某种树类,但对于概念上相当简单的东西来说,这看起来像是很多工作。

任何想法或建议将不胜感激。
干杯,
戴维


我只回答第二个问题:

首先,保留一个字典映射一个维基百科文章标题到下一个。 这将使您能够轻松快速地检查您是否已经点击过您之前找到的文章。 基本上这只是存储一个有向图的顶点,它们的起点索引。

如果你达到了Python字典效率不够高的地步(它确实有很大的内存开销,一旦有数百万项内存可能成为问题),你可以找到一个更有效的图形数据结构来满足你的需求。

编辑

好的,我会回答第一个问题......

对于第一部分,我强烈建议使用MediaWiki API,而不是获取HTML版本并解析它。 该API可以查询某些类型的链接,例如只是维基链接或只是跨语言链接。 另外,这个API还有Python客户端库,它可以使Python代码简单地使用它。

如果它提供了一个全面的,且有详细记录的API,请不要分析网站的HTML!


对于第一部分,不可能使用CSS选择器来查找括号,因为就HTML而言,括号只是文本。

如果我是你,我会使用选择器来查找对游戏有效的所有相关段落元素。 然后,我会查看段落元素的文本,并删除无效的任何内容 - 例如,括号内的任何内容以及斜体标记之间的任何内容。 然后,我会为我需要的链接元素搜索这个处理过的文本。 这比手动处理整个html文档略好一些。

我不确定我是否遵循了第二部分的具体内容,而是将搜索结果表示为树:当您正在寻找周期时,这是一个坏主意,树​​无法表示。

对于数据结构,我会列出“节点”,其中一个节点代表一个页面,并具有一个URL和一个发生次数。 然后我会使用蛮力算法来比较节点列表 - 如果两个列表的节点相同,则可以合并它们,从而增加每个镜像节点的“发生次数”。

我不会使用标准的python'list',因为它不能自行循环。 也许创建你自己的链表实现来包含节点。

链接地址: http://www.djcxy.com/p/62845.html

上一篇: Wikipedia philosophy game diagram in python and R

下一篇: Extract the first paragraph from a Wikipedia article (Python)