跳转到内容

XQuery/维基百科页面抓取

来自维基教科书,开放的书籍,为开放的世界

页面抓取允许任何网页成为适合转换的原始数据的来源。此示例获取维基百科当前事件页面上的数据 2007 年 9 月 24 日 并转换为 一个简单的 HTML 页面

XQuery 页面抓取器的关键组件是

  1. fn:doc 函数,它接受一个 URL 并将页面检索为 XML。许多页面格式不正确的 XML,但维基百科页面是格式良好的。
  2. 如果页面具有默认命名空间,则设置命名空间。此页面具有 "http://www.w3.org/1999/xhtml" 的默认命名空间,因此必须声明命名空间,并在访问页面的 XML 的路径表达式中使用其命名空间前缀。
  3. 选定内容路径的标识。在本例中,内容位于具有“description”类的 td 标签中。
  4. 重新设置任何相对 URL。此处指向维基百科文章的链接具有相对 URL。为了重新设置它们,XML 被序列化为一个字符串,并使用 util:serialize(),使用 replace 编辑相对 URL,并将字符串使用 util:parse() 转换回 XML。

从维基百科当前事件页面提取数据的示例 XQuery

[编辑 | 编辑源代码]

在此示例中,需要进行一些日期重新格式化,因为页面 URL 中的日期格式不是 XML 格式化的日期。包含指向前一天和后一天的链接,利用 XQuery 日期算术。

declare namespace h= "http://www.w3.org/1999/xhtml" ;
declare option exist:serialize "method=xhtml media-type=text/html indent=yes";
declare variable $months := 
 ("January","February","March","April","May","June","July","August","September","October","November","December")
;
declare function local:wikidate($date as xs:date) as xs:string {
      concat(year-from-date($date),"_",
                   $months[month-from-date($date)],"_",
                   day-from-date($date)
                   )
};
declare function local:displaydate($date as xs:date) as xs:string {
      concat(day-from-date($date)," ",
                   $months[month-from-date($date)],", ",
                   year-from-date($date)
                   )
};

declare function local:add-base($element , $base as xs:string, $delimiter as xs:string)   {
    let $evtext := util:serialize($element,())
    let $evtext := replace($evtext,
                           concat ("href=",$delimiter,"/"),
                           concat("href=",$delimiter,$base,"/")
                   )
    return util:parse($evtext)
};

let $date := xs:date(request:get-parameter("date",()))
let $wikidate := local:wikidate($date)
let $url := concat("http://en.wikipedia.org/wiki/Portal:Current_events/",$wikidate)
let $wikipage := doc($url)
let $desc := $wikipage//h:td[@class="description"]
let $nextDay := $date + xs:dayTimeDuration("P1D")
let $previousDay := $date - xs:dayTimeDuration("P1D")
return
<html>
   <body>
    <h1>Current events from <a href="{$url}">Wikipedia</a></h1>
      <h2>Wiki Events for        
                <span style="font-size:12;"><a href="wikidate.xq?date={$previousDay}">{local:displaydate($previousDay)}</a></span>&#160;
               {local:displaydate($date)}
               <span style="font-size:12;"><a href="wikidate.xq?date={$nextDay}">{local:displaydate($nextDay)}</a></span>&#160;
      </h2>
            {
            local:add-base($desc/*,"http://en.wikipedia.org",'"')
            }
   </body>
</html>
华夏公益教科书