有没有办法在一个类别中获取所有维基百科文章的列表,包括所有子类别?
我尝试使用PHP脚本从类别页面中提取链接,但似乎没有可能获得包括子类别在内的所有文章。
答案 0 :(得分:4)
您可以使用MediaWiki API执行此操作,特别是list=categorymembers
。
这是一个随机的例子:
上面的链接将以XML格式为您提供Category:Defunct airports in Prince Edward Island中所有页面的列表(默认情况下打印得非常方便)。您可以通过在网址上附加适当的参数(例如format=xml
或format=json
),从各种机器可读的output formats中进行选择。
请注意,通常,上面显示的查询将包含该类别中的所有页面,包括文章和子类别。您只能通过包含参数cmnamespace=0
将其限制为文章,但之后您将错过任何子类别。 (不过,您可以随时使用cmnamespace=14
单独获取这些内容。)
您可能需要该信息的原因是list=categorymembers
查询本身将不递归到子类别中,因此如果您需要,则必须自己执行此操作。但是,如果你这样做,请注意不要陷入任何类别循环,并确保对结果进行健全性检查 - 很容易得到方式比你预期更多的页面完整的子类别遍历。
此外,默认情况下,单个categorymembers
查询最多可获得10个结果。您可以通过在查询中包含参数cmlimit=max
将该限制增加到500(或5000,如果您碰巧有权访问维基百科上的bot-flagged account,但即使这样,也可能会削减非常大的类别关闭。如果发生这种情况,查询结果将包含query continuation部分,该部分将告诉您(或您的MW API client library)如何使用其他查询获取其余页面。
编辑:我有点想念你特别询问在子类别中获取文章的事实。这里有一些基本的(未经测试的)示例代码,说明如何使用Apibot 0.40桥接接口(我只是随机选择),因为它看起来像一个不错的PHP MW API客户端库,所以我不需要担心查询延续等细节:
function pages_under_category ( $category ) {
global $bridge; // I'll assume you've set this up in advance
$queue = array( $category ); // categories to fetch
$seen = array( $category ); // categories already seen
$pages = array(); // result pages (format: $title => array( $cat, ... ))
while ( !empty( $queue ) ) {
$cat = array_shift( $queue );
$query = $bridge->query_list_categorymembers();
$query->title = $cat; // assume "Category:" prefix is included
// fetch the contents of the category
$query_result = $query->xfer();
while ( $query_result ) {
foreach ( $query->data as $page_data ) {
$title = $page_data['title'];
$namespace = $page_data['ns'];
if ( $namespace == 0 ) { // it's an article!
if ( !isset( $pages[$title] ) ) {
$pages[$title] = array();
}
$pages[$title][] = $cat; // record where we found it
}
else if ( $namespace == 14 ) { // it's a subcategory
if ( !in_array( $title, $seen ) ) {
$seen[] = $title; // avoid loops!
$queue[] = $title;
}
}
}
$query_result = $query->next();
}
}
return $pages;
}
您可能想要添加到上面代码中的一个功能是对结果大小/迭代次数的某种限制,因此即使递归检索以某种方式找到它的路径,比如Category:Contents,它也是如此将在某个时候停止尝试列出维基百科上的每一页。
答案 1 :(得分:0)
这可以通过PetScan完成,例如,在示例https://petscan.wmflabs.org/?psid=19820
您可以选择进入子类别的深度,添加esarch术语和/或排除属于指定其他类别的页面。