HTMLページのコンテンツに対するSPARQLクエリ

こんにちは。

会議に参加した後、アイデアを思いつきました。

この投稿では、 grabおよびrdflibライブラリーの使用例と、Webページのコンテンツに対してSPARQLクエリを実行するための既製のクラスを提供します。



このツールを使用して、構造化された形式(rdf-triples、xml、json)で情報を提供しないサイトからの情報を、「マシン」が理解できる形式に変換することになっています。





htmlコンテンツに対してSPARQLクエリを実行するには、ローカルrdfリポジトリを作成し、grabを使用してhtmlページから取得した情報を入力する必要があります。



まず、必要なすべてのライブラリをインポートし、SPARQLプラグインの使用を登録します。



# -*- coding: utf-8 -*- import grab import rdflib from rdflib import * from rdflib import plugin plugin.register( 'sparql', rdflib.query.Processor, 'rdfextras.sparql.processor', 'Processor') plugin.register( 'sparql', rdflib.query.Result, 'rdfextras.sparql.query', 'SPARQLQueryResult')
      
      







クラスを定義し、そのコンストラクタを構築します。

デザイナーは、解決してリポジトリに配置する必要があるページのURLを受け入れることができ、名前空間定義の非標準の場所を決定することもできます。



 class SQtHD(): ''' sparql query to html documents ''' def __init__(self,url=None,htmlNamespace='http://localhost/rdf/html#'): ''' Constructor ''' self.__grab__=grab.Grab()#  self.__storage__=Graph()#  self.__namespace__=Namespace(htmlNamespace)#   self.__storage__.bind('html', URIRef(htmlNamespace))#     self.__initnamespace__=dict(self.__storage__.namespace_manager.namespaces()) if url:# ,       . self.__store__(url)
      
      







次に、ページのコンテンツでリポジトリを埋めるためのユーティリティ関数を定義する必要があります。



  def __store__(self,url): self.__storage__.remove((None,None,None))#  self.__grab__.go(url)#      grab root=self.__grab__.tree.getroottree().getroot() self.__parse__(root)#  .
      
      







次のアイテム情報はローカルストレージに保存されます。



次のユーティリティ関数は、必要な情報を収集してリポジトリに追加する要素のツリーを再帰的に通過します。



  def __parse__(self,element,parent=None,children_position=None,children_level=0): current_element=BNode() children_elements=element.getchildren() if str(element.tag)=='<built-in function Comment>': self.__storage__.add((current_element, RDF.type, self.__namespace__['comment'])) else: self.__storage__.add((current_element, RDF.type, self.__namespace__[element.tag])) if not parent==None: self.__storage__.add((current_element,self.__namespace__['parent'],parent)) self.__storage__.add((parent,self.__namespace__['children'], current_element)) self.__storage__.add((current_element,self.__namespace__['children_position'], Literal(children_position))) self.__storage__.add((current_element,self.__namespace__['children_level'], Literal(children_level))) if element.text and len(element.text.strip())>0: self.__storage__.add((current_element,self.__namespace__['text'], Literal(element.text.strip()))) if element.text_content() and len(element.text_content().strip())>0: self.__storage__.add((current_element,self.__namespace__['text_content'], Literal(element.text_content().strip()))) self.__storage__.add((current_element,self.__namespace__['children_count'], Literal(len(children_elements)))) for i in element.attrib: self.__storage__.add((current_element,self.__namespace__[i], Literal(element.attrib[i]))) for i in range(len(children_elements)): self.__parse__(children_elements[i],current_element,i,children_level+1)
      
      







この関数は、ローカルストレージに対してSPARQLクエリを実行します。



  def executeQuery(self,query,url=None): ''' execute query on storadge ''' if url:# ,       . self.__store__(url) return self.__storage__.query(query, initNs=self.__initnamespace__)#   .
      
      







この関数は、指定されたページのコンテンツでリポジトリを埋めます。



  def loadStoradge(self,url): ''' load and parse html page to local rdf storadge ''' self.__store__(url)
      
      







最後に、いくつかの簡単なクエリの例を示します。



 if __name__ == "__main__": endPoint = SQtHD()#   SQtHD endPoint.loadStoradge('http://habrahabr.ru')#    print "All sources for images given by tag <img>:"#     q=endPoint.executeQuery('SELECT DISTINCT ?src { ?a rdf:type html:img. ?a html:src ?src. }') for row in q.result: print row print print "All link urls:"#     q=endPoint.executeQuery('SELECT DISTINCT ?href { ?a rdf:type html:a. ?a html:href ?href. }') for row in q.result: print row print print "All class names for elements:"#     q=endPoint.executeQuery('SELECT DISTINCT ?class { ?a html:class ?class. }') for row in q.result: print row print ''' print "All scripts (without loaded by src):"#   . q=endPoint.executeQuery('SELECT ?text { ?a rdf:type html:script. ?a html:text ?text. }') for row in q.result: print row print''' print "All script srcs:"#   . q=endPoint.executeQuery('SELECT ?src { ?a rdf:type html:script. ?a html:src ?src. }') for row in q.result: print row print
      
      







すべてのスクリプトリンクを表示するリクエストを実行した結果:



 All script srcs: /javascripts/1341931979/all.js /javascripts/1341931979/_parts/posts.js /javascripts/1341931979/_parts/to_top.js /javascripts/1341931979/_parts/shortcuts.js /javascripts/1341931979/libs/jquery.form.js /javascripts/1341931979/facebook_reader.js /js/1341931979/adriver.core.2.js /javascripts/1341931979/libs/highlight.js /javascripts/1341931979/hubs/all.js /javascripts/1341931979/posts/all.js
      
      







したがって、リポジトリを埋めるには3つの方法があります。

  1. クラスの初期化時
  2. loadStoradge関数経由
  3. ストレージリクエストごと




GISTプロジェクトには、xmlを使用した名前空間定義も含まれています。 名前空間は、タグが何であるかを決定し、必要なプロパティと関係を設定し、html 4タグも定義します。

推奨読書:

「セマンティックWebのプログラミング」Toby Segaran、Colin Evans、Jamie Taylor



All Articles