上传应用程序到谷歌商店

常用缩略语 API:应用程序编程接口 DOM:文档对象模型 HTTP:超文本传输​​协议 HTML:超文本标记语言 ISBN:国际标准书号 REST:代表性状态转移 URL:统一资源定位符 XML:可扩展标记语言

如果您以任何方式与出版业建立联系,或者即使您只是一个狂热的读者,那么您都有可能听说过Google图书。 Google试图通过扫描数百万本书并将其提供以供预览或在线购买来创建世界上最大的可搜索数字图书馆。 这也是Google最具争议的项目之一,也是最近才于2009年11月解决的集体诉讼的重点。

除了进行有趣的饮水机对话之外,从开发人员的角度来看,Google图书还因其Data API而引起人们的兴趣。 使用此API,开发人员可以读取和搜索Google图书数据库中符合用户指定条件的图书,并在其他Web应用程序中使用这些搜索的结果。 您可以通过任何具有XML功能的开发工具包访问遵循REST模型的该API。 该API已经具有用于PHP,Java™和其他常见编程语言的客户端库。

本文将向您介绍Google图书搜索数据API,向您展示如何将图书搜索结果与自定义PHP应用程序集成和使用。 它包括按关键字,按语言或按作者搜索书籍的示例; 检索图书数据(包括ISBN号和缩略图); 并对数据库中已有的图书添加评论和评分。 快来开始吧!

了解图书搜索供稿

在启动PHP代码之前,请按顺序输入一些有关Google Book Search Data API的信息。 与所有基于REST的服务一样,API接受包含一个或多个XML编码输入参数的HTTP请求,并返回可以在任何支持XML的客户端中解析的XML编码响应。 使用Google图书搜索数据API,响应始终由包含请求的信息的Atom提要组成。

php
清单1:示例Google图书搜索供稿
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom' 
 xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' 
 xmlns:gbs='http://schemas.google.com/books/2008' 
 xmlns:dc='http://purl.org/dc/terms' 
 xmlns:gd='http://schemas.google.com/g/2005'>
  <id>http://www.google.com/books/feeds/volumes</id>
  <updated>2009-12-28T06:14:28.000Z</updated>
  <category scheme='http://schemas.google.com/g/2005#kind' 
   term='http://schemas.google.com/books/2008#volume'/>
  <title type='text'>Search results for php</title>
  <link rel='alternate' type='text/html' href='http://www.google.com'/>
  <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' 
   href='http://www.google.com/books/feeds/volumes'/>
  <link rel='self' type='application/atom+xml' 
   href='http://www.google.com/books/feeds/volumes?q=php'/>
  <link rel='next' type='application/atom+xml' 
   href='http://www.google.com/books/feeds/volumes?q=php
   &start-index=11&max-results=10'/>
  <author>
    <name>Google Books Search</name>
    <uri>http://www.google.com</uri>
  </author>
  <generator version='beta'>Google Book Search data API</generator>
  <openSearch:totalResults>277</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>10</openSearch:itemsPerPage>
  <entry>
    <id>http://www.google.com/books/feeds/volumes/tywvv3ULal0C</id>
    <updated>2009-12-28T06:14:28.000Z</updated>
    <category scheme='http://schemas.google.com/g/2005#kind' 
      term='http://schemas.google.com/books/2008#volume'/>
    <title type='text'>Programming PHP</title>
    <link rel='http://schemas.google.com/books/2008/thumbnail' 
      type='image/x-unknown' href='http://bks8.books.google.com/books?
      id=tywvv3ULal0C&printsec=frontcover&img=1&zoom=5
      &edge=curl&sig=ACfU3U0WFIZOyvLPjIv7jqlX4XZ7GI4TAg
      &source=gbs_gdata'/>
    <link rel='http://schemas.google.com/books/2008/info' type='text/html' 
     href='http://books.google.com/books?id=tywvv3ULal0C&dq=php
     &ie=ISO-8859-1&source=gbs_gdata'/>
    <link rel='http://schemas.google.com/books/2008/preview' type='text/html' 
     href='http://books.google.com/books?id=tywvv3ULal0C
     &printsec=frontcover&dq=php&ie=ISO-8859-1&cd=1
     &source=gbs_gdata'/>
    <link rel='http://schemas.google.com/books/2008/annotation' 
     type='application/atom+xml' 
     href='http://www.google.com/books/feeds/users/me/volumes'/>
    <link rel='alternate' type='text/html' 
     href='http://books.google.com/books?
     id=tywvv3ULal0C&dq=php&ie=ISO-8859-1'/>
    <link rel='self' type='application/atom+xml' 
     href='http://www.google.com/books/feeds/volumes/tywvv3ULal0C'/>
    <gbs:embeddability value='http://schemas.google.com/books/2008#embeddable'/>
    <gbs:openAccess value='http://schemas.google.com/books/2008#disabled'/>
    <gbs:viewability value='http://schemas.google.com/books/2008#view_partial'/>
    <dc:creator>Rasmus Lerdorf</dc:creator>
    <dc:creator>Kevin Tatroe</dc:creator>
    <dc:creator>Peter MacIntyre</dc:creator>
    <dc:date>2006</dc:date>
    <dc:description>With style tips and practical programming advice, 
     this book will help you become not just a PHP programmer, 
     but a &quot;good&quot; PHP programmer.</dc:description>
    <dc:format>521 pages</dc:format>
    <dc:format>book</dc:format>
    <dc:identifier>tywvv3ULal0C</dc:identifier>
    <dc:identifier>ISBN:0596006810</dc:identifier>
    <dc:identifier>ISBN:9780596006815</dc:identifier>
    <dc:publisher>O'Reilly Media, Inc.</dc:publisher>
    <dc:subject>Computers</dc:subject>
    <dc:title>Programming PHP</dc:title>
  </entry>
  <entry>
  ...
  </entry>
</feed>

快速浏览一下此输出,以熟悉其主要元素:

<feed><link><openSearch:><link><openSearch:><feed><entry><entry><entry><link><dc:>

并非所有Google Book Search Data API函数都可以通过这种方式公开访问。 尽管您无需身份验证即可访问搜索功能,但如果您是可以提供有效的Google帐户用户名的经过身份验证的用户,则仅可以访问其他用于修改数据的功能(包括添加评论和标签的功能,或将图书添加到用户的图书馆的功能)和密码。 您将在本文中看到两种类型的函数的示例。

执行图书搜索查询

既然您知道如何通过公共REST API访问Google图书搜索结果,那么看看如何在PHP应用程序中执行相同的操作。 当然,一种方法是使用PHP的内置XML处理扩展(SimpleXML,DOM或XMLReader)来解析Google图书搜索返回的XML提要,并从中提取相关信息片段。 但是,这不是很方便,尤其是在处理大量提要或大量命名空间信息时。 因此,本文将使用不同的方法:Zend Framework的Zend_Gdata客户端库,该库专门为尝试将PHP应用程序与Google Data API集成的开发人员而设计。

该Zend_Gdata库可以作为Zend框架的一部分,或作为一个独立的软件包(见下载相关信息中的链接)。 它包括一个专门用于与Google Book Search Data API配合使用的模块,提供了预定义的类和方法来简化数据访问和身份验证。 该库不仅为您的应用程序提供了经过社区测试的可靠代码库,而且在使用它时,您可以专注于核心应用程序功能,而不是导航XML树或处理自定义名称空间的本质。

清单2说明了如何使用Zend_Gdata客户端库通过Google图书搜索数据API检索和解析图书搜索结果的供稿:

清单2:使用Zend_Gdata库检索搜索结果
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Books');
Zend_Loader::loadClass('Zend_Gdata_Books_VolumeQuery');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');

// set credentials for ClientLogin authentication
$user = "[email protected]";
$pass = "secret";

try {
  // perform login 
  $client = Zend_Gdata_ClientLogin::getHttpClient(
    $user, $pass, 'print');
  $client->setHeaders('X-Forwarded-For', $_SERVER['REMOTE_ADDR']);
  $books = new Zend_Gdata_Books($client);

  // prepare and execute search query
  $query = new Zend_Gdata_Books_VolumeQuery;
  $query->setQuery(urlencode('robert crais'));
  $feed = $books->getVolumeFeed($query);  
} catch (Exception $e) {
  die('ERROR:' . $e->getMessage());  
}
?>
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Searching for book titles</title>
  </head>
  <body>
    
    <h2><?php echo $feed->title; ?></h2>
    <div>
    <?php echo $feed->totalResults; ?> result(s) found.
    </div>
  
    <div id="results")
      <ol>
        <?php foreach ($feed as $entry): ?>
        <li>      
          <?php echo $entry->getTitle(); ?>
        </li>      
        <?php endforeach; ?>
      </ol>  
    </div>  
    
  </body>
</html>

清单2首先加载Zend类库,然后初始化Zend_Http_Client类的实例。 此客户端将获得创建与Google图书搜索服务的身份验证连接所需的用户凭据。 创建经过身份验证的连接后,将初始化Zend_Gdata_Books类的新实例。 此类用作所有后续与Google图书搜索数据API交互的控制点。

getVolumeFeed()getVolumeFeed()setQuery()getVolumeFeed()<entry>

图1展示了您可能看到的输出-匹配关键字'robert crais'的所有图书的列表:

图1.基本Google Books API搜索的结果

有了基本的了解之后,很容易修改清单2以使其更具交互性。 清单3演示了如何添加一个搜索表单,该表单可用于执行用户提供的图书搜索查询:

清单3:检索与用户提供的关键字匹配的搜索结果
<?php
if (isset($_POST['submit'])) {
  // load Zend Gdata libraries
  require_once 'Zend/Loader.php';
  Zend_Loader::loadClass('Zend_Gdata_Books');
  Zend_Loader::loadClass('Zend_Gdata_Books_VolumeQuery');
  Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
  
  // set credentials for ClientLogin authentication
  $user = "[email protected]";
  $pass = "secret";
  
  try {
    // perform login 
    $client = Zend_Gdata_ClientLogin::getHttpClient(
      $user, $pass, 'print');
    $client->setHeaders('X-Forwarded-For', $_SERVER['REMOTE_ADDR']);
    $books = new Zend_Gdata_Books($client);
  
    // prepare and execute search query
    $query = new Zend_Gdata_Books_VolumeQuery;
    $query->setQuery(urlencode($_POST['q']));
    $feed = $books->getVolumeFeed($query);  
  } catch (Exception $e) {
    die('ERROR:' . $e->getMessage());  
  }
}
?>
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Searching for book titles</title>
  </head>
  <body>
    
    <h2>Search</h2>
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for: 
    <input type="text" name="q" value="<?php echo isset($_POST['q']) ? 
     $_POST['q'] : ''; ?>" />
    <input type="submit" name="submit" value="Go" />
    </form>
  
    <?php if (isset($feed)): ?>
    <h2>Search results for '<?php echo $_POST['q']; ?>'</h2>
    <div>
    <?php echo $feed->totalResults; ?> result(s) found.
    </div>
  
    <div id="results")
      <ol>
        <?php foreach ($feed as $entry): ?>
        <li>      
          <a href="<?php echo $entry->getInfoLink()->getHref(); ?>">
          <?php echo $entry->getTitle(); ?></a>
        </li>      
        <?php endforeach; ?>
      </ol>  
    </div>  
    <?php endif; ?>
    
  </body>
</html>

图2展示了一个搜索“印度烹饪”所产生的输出的示例:

图2.基本Google Books API搜索的结果
Zend_Gdata_Books_VolumeEntry::getInfoLink()
图3.书籍详细信息页面
urlencode()

检索详细的图书信息

如清单1所示 ,除书名外,Google图书搜索数据API返回的批量供稿包含大量信息:作者和出版商名称,ISBN号,页数,主题等上。 使用Zend_Gdata_Books,所有这些信息都表示为一组对象,您可以在PHP脚本的范围内访问和操作这些对象,以创建内容更丰富的搜索结果页面。

为了说明这一点,请考虑清单4 :

清单4:检索书籍详细信息
<?php
if (isset($_POST['submit'])) {
  // load Zend Gdata libraries
  require_once 'Zend/Loader.php';
  Zend_Loader::loadClass('Zend_Gdata_Books');
  Zend_Loader::loadClass('Zend_Gdata_Books_VolumeQuery');
  Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
  
  // set credentials for ClientLogin authentication
  $user = "[email protected]";
  $pass = "secret";
  
  try {
    // perform login 
    $client = Zend_Gdata_ClientLogin::getHttpClient(
      $user, $pass, 'print');
    $client->setHeaders('X-Forwarded-For', $_SERVER['REMOTE_ADDR']);
    $books = new Zend_Gdata_Books($client);
  
    // prepare and execute search query
    $query = new Zend_Gdata_Books_VolumeQuery;
    $query->setQuery(urlencode($_POST['q']));
    $feed = $books->getVolumeFeed($query);  
  } catch (Exception $e) {
    die('ERROR:' . $e->getMessage());  
  }
}
?>
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Searching for book titles</title>
    <style>
    .entry {
      height: 120px;
      border-bottom: dashed silver 2px;
      padding-top: 10px;
    }
    
    .thumbnail {
      float: left;  
      border: solid black 2px;
      padding: 2px;
      margin-right: 10px;
    }
    
    .desc {
      font-style: italic;  
    }
    
    .small {
      font-size: smaller;  
    }    
    </style>    
  </head>
  <body>
    
    <h2>Search</h2>
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for: 
    <input type="text" name="q" value="<?php echo isset($_POST['q']) ? 
     $_POST['q'] : ''; ?>" />
    <input type="submit" name="submit" value="Go" />
    </form>
  
    <?php if (isset($feed)): ?>
      <h2>Search results for '<?php echo $_POST['q']; ?>'</h2>
      <div>
      <?php echo $feed->totalResults; ?> result(s) found.
      </div>
    
      <div id="results">
      <?php $x = 1; ?>
      <?php foreach ($feed as $entry): ?>
    
        <?php    
        //print_r($entry);   
        $book = new stdClass;
        
        // get title
        if (is_array($entry->getTitles())) {
          foreach ($entry->getTitles() as $title) {
            $book->titles[] = $title->getText(); 
          }
        }
        
        // get authors
        if (is_array($entry->getCreators())) {
          foreach ($entry->getCreators() as $creator) {
            $book->authors[] = $creator->getText(); 
          }
        }
    
        // get publishers
        if (is_array($entry->getPublishers())) {
          foreach ($entry->getPublishers() as $publisher) {
            $book->publishers[] = $publisher->getText(); 
          }
        }
        
        // get publication date
        if (is_array($entry->getDates())) {
          $arr = $entry->getDates();
          $book->pubdate = (is_object($arr[0])) ? 
           $arr[0]->getText() : 'Unspecified'; 
        }
    
        // get ISBN numbers
        if (is_array($entry->getIdentifiers())) {
          foreach ($entry->getIdentifiers() as $id) {
            if (preg_match('/ISBN/', $id->getText())) {
              $book->isbn[] = $id->getText(); 
            }  
          }
        }
        
        // get first subject
        if (is_array($entry->getSubjects())) {
          $arr = $entry->getSubjects();
          $book->subject = is_object($arr[0]) ? 
           $arr[0]->getText() : 'Unspecified'; 
        }
        
        // get first description
        if (is_array($entry->getDescriptions())) {
          $arr = $entry->getDescriptions();
          $book->desc = is_object($arr[0]) ? 
           $arr[0]->getText() : 'No description available'; 
        }            
        ?>
      
        <div class="entry">
          <div class="thumbnail">
            <img src="<?php echo ($entry->getThumbnailLink()) ? 
             $entry->getThumbnailLink()->getHref() : ''; ?>" />      
          </div>
          <div class="data">
          <?php echo $x; ?>. <?php echo ucwords(@implode(': ', 
           $book->titles)); ?><br/>
          <?php echo @implode(', ', $book->authors); ?> |
          <?php echo @implode(', ', $book->publishers); ?> |
          <?php echo $book->subject; ?> |
          <?php echo date('d M Y', strtotime($book->pubdate)); ?> <br/>
          <span class="desc"><?php echo $book->desc; ?></span> <br/>
          <span class="small"><?php echo @implode(', ', $book->isbn); ?> |       
            <a href="<?php echo $entry->getInfoLink()->getHref(); ?>">
            More information</a>   
          </span>
          </div>
        </div>      
        <?php $x++; ?>
      <?php endforeach; ?>
    <?php endif; ?>
    
  </body>
</html>

清单4引入了Zend_Gdata_Books_VolumeEntry类的许多新方法。 以下是重要提示的快速列表:

getDates()getCreators()getPublishers()getSubjects()getDescriptions()getTitles()getIdentifiers()getThumbnailLink()getVolumeId()

所有这些方法都返回一个对象数组,这些对象对应于各种Dublin Core元数据元素。 然后由开发人员访问每个数组的元素并使用其中的信息来重新构成搜索结果。 图4说明了结果的示例。

图4. Google Books API搜索的结果,搜索结果经过增强,包括封面图像和其他书籍数据

使用查询过滤器

您可能已经注意到,在所有前面的示例中,即使元素实际上指示出更高数量的匹配项,搜索结果供稿也仅包含10个条目。 这是因为默认情况下,Google图书搜索供稿每个供稿最多可匹配10个匹配项。 这绝不是一成不变的。 您可以通过向REST查询添加以下一些参数来轻松自定义API输出:

start-indexmax-resultsmin-viewability

除了这些参数之外,您还可以在搜索查询中添加其他过滤器,以按书名,作者,出版者,语言,主题,描述或ISBN号搜索书籍。 清单5演示了如何实现:

清单5:按作者,标题和可见性过滤搜索结果
<?php
if (isset($_POST['submit'])) {
  // load Zend Gdata libraries
  require_once 'Zend/Loader.php';
  Zend_Loader::loadClass('Zend_Gdata_Books');
  Zend_Loader::loadClass('Zend_Gdata_Books_VolumeQuery');
  Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
  
  // set credentials for ClientLogin authentication
  $user = "[email protected]";
  $pass = "secret";
  
  try {
    // perform login 
    $client = Zend_Gdata_ClientLogin::getHttpClient(
      $user, $pass, 'print');
    $client->setHeaders('X-Forwarded-For', $_SERVER['REMOTE_ADDR']);
    $books = new Zend_Gdata_Books($client);
  
    // prepare and execute search query
    $query = new Zend_Gdata_Books_VolumeQuery;
    $queryStr = '';
    if (!empty($_POST['title'])) {
      $queryStr .= '+intitle:'.urlencode($_POST['title']);
    }
    if (!empty($_POST['author'])) {
      $queryStr .= '+inauthor:'.urlencode($_POST['author']);
    }    
    $query->setQuery($queryStr);
    $query->setMinViewability($_POST['v']);
    $query->setMaxResults(20);
    
    $feed = $books->getVolumeFeed($query);  
  } catch (Exception $e) {
    die('ERROR:' . $e->getMessage());  
  }
}
?>
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Searching for book titles</title>
    <style>
    .entry {
      height: 120px;
      border-bottom: dashed silver 2px;
      padding-top: 10px;
    }
    
    .thumbnail {
      float: left;  
      border: solid black 2px;
      padding: 2px;
      margin-right: 10px;
    }
    
    .desc {
      font-style: italic;  
    }
    
    .small {
      font-size: smaller;  
    }    
    </style>    
  </head>
  <body>
    
    <h2>Search</h2>
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Title: 
    <input type="text" name="title" value="<?php echo isset($_POST['title']) ? 
     $_POST['title'] : ''; ?>" />
    
    Author: 
    <input type="text" name="author" value="<?php echo isset($_POST['author']) ? 
     $_POST['author'] : ''; ?>" />

    Viewability:
    <select name="v">
      <option value="none">Any</option>
      <option value="partial_view">Partial</option>
      <option value="full_view">Full</option>
    </select>    

    <input type="submit" name="submit" value="Go" />
    </form>
  
    <?php if (isset($feed)): ?>
      <h2>Search results for '<?php echo $query->getQuery(); ?>'
      </h2>
      <div>
      <?php echo $feed->totalResults; ?> result(s) found.
      </div>
    
      <div id="results">
      <?php $x = 1; ?>
      <?php foreach ($feed as $entry): ?>
    
        <?php    
        //print_r($entry);   
        $book = new stdClass;
        
        // get title
        if (is_array($entry->getTitles())) {
          foreach ($entry->getTitles() as $title) {
            $book->titles[] = $title->getText(); 
          }
        }
        
        // get authors
        if (is_array($entry->getCreators())) {
          foreach ($entry->getCreators() as $creator) {
            $book->authors[] = $creator->getText(); 
          }
        }
    
        // get publishers
        if (is_array($entry->getPublishers())) {
          foreach ($entry->getPublishers() as $publisher) {
            $book->publishers[] = $publisher->getText(); 
          }
        }
        
        // get publication date
        if (is_array($entry->getDates())) {
          $arr = $entry->getDates();
          $book->pubdate = (is_object($arr[0])) ? 
           $arr[0]->getText() : 'Unspecified'; 
        }
    
        // get ISBN numbers
        if (is_array($entry->getIdentifiers())) {
          foreach ($entry->getIdentifiers() as $id) {
            if (preg_match('/ISBN/', $id->getText())) {
              $book->isbn[] = $id->getText(); 
            }  
          }
        }
        
        // get first subject
        if (is_array($entry->getSubjects())) {
          $arr = $entry->getSubjects();
          $book->subject = is_object($arr[0]) ? 
           $arr[0]->getText() : 'Unspecified'; 
        }
        
        // get first description
        if (is_array($entry->getDescriptions())) {
          $arr = $entry->getDescriptions();
          $book->desc = is_object($arr[0]) ? 
           $arr[0]->getText() : 'No description available'; 
        }            
        ?>
      
        <div class="entry">
          <div class="thumbnail">
            <img src="<?php echo ($entry->getThumbnailLink()) ? 
             $entry->getThumbnailLink()->getHref() : ''; ?>" />      
          </div>
          <div class="data">
          <?php echo $x; ?>. <?php echo ucwords(@implode(': ', 
           $book->titles)); ?><br/>
          <?php echo @implode(', ', $book->authors); ?> |
          <?php echo @implode(', ', $book->publishers); ?> |
          <?php echo $book->subject; ?> |
          <?php echo date('d M Y', strtotime($book->pubdate)); ?> <br/>
          <span class="desc"><?php echo $book->desc; ?></span> 
          <br/>
          <span class="small"><?php echo @implode(', ', $book->isbn); ?> |       
            <a href="<?php echo $entry->getInfoLink()->getHref(); ?>">
            More information</a>   
          </span>
          </div>
        </div>      
        <?php $x++; ?>
      <?php endforeach; ?>
    <?php endif; ?>
    
  </body>
</html>
setMinViewability()setMaxResults()min-viewabilitymax-results

图5和图6展示了清单5的输出,前者显示标题搜索的结果,而后者显示组合的作者/标题搜索的结果。

图5. Google图书搜索的结果,按标题过滤
图6. Google Books API搜索的结果,按作者和标题名称过滤

访问用户库

除了允许公共搜索外,Google图书搜索还允许经过身份验证的用户创建自己的虚拟图书库。 此“我的图书馆”功能允许用户查看和标记书籍,以及与其他用户创建和共享书籍收藏。 与其他Google图书搜索功能一样,它可以通过Google图书搜索数据API使用。

要查看“我的图书馆”功能的工作原理,请使用您的Google帐户登录到Google图书搜索,输入搜索词,然后使用每个搜索结果旁边显示的“添加到我的图书馆”链接开始创建虚拟图书馆。 您可以随时使用每个页面右上角的“我的库”链接访问该库。 图7展示了一个这样的用户库的示例:

图7. Google图书网站上的用户库
<entry>getUserLibraryFeed()
清单6:检索用户库内容
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Books');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');

// set credentials for ClientLogin authentication
$user = "[email protected]";
$pass = "secret";

try {
  // perform login 
  $client = Zend_Gdata_ClientLogin::getHttpClient(
    $user, $pass, 'print');
  $client->setHeaders('X-Forwarded-For', $_SERVER['REMOTE_ADDR']);
  $books = new Zend_Gdata_Books($client);

  // get authenticated user's library feed
  $feed = $books->getUserLibraryFeed();
} catch (Exception $e) {
  die('ERROR:' . $e->getMessage());  
}
?>
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Displaying a user's library</title>
    <style>
    .entry {
      height: 120px;
      border-bottom: dashed silver 2px;
      padding-top: 10px;
    }
    
    .thumbnail {
      float: left;  
      border: solid black 2px;
      padding: 2px;
      margin-right: 10px;
    }
    
    .desc {
      font-style: italic;  
    }
    
    .small {
      font-size: smaller;  
    }    
    </style>    
  </head>
  <body>    
    <?php if (isset($feed)): ?>
      <h2>My Library</h2>
      <div>
      <?php echo $feed->totalResults; ?> result(s) found.
      </div>
    
      <div id="results">
      <?php $x = 1; ?>
      <?php foreach ($feed as $entry): ?>
    
      <?php    
      $book = new stdClass;
      
      // get title
      if (is_array($entry->getTitles())) {
        foreach ($entry->getTitles() as $title) {
          $book->titles[] = $title->getText(); 
        }
      }
      
      // get authors
      if (is_array($entry->getCreators())) {
        foreach ($entry->getCreators() as $creator) {
          $book->authors[] = $creator->getText(); 
        }
      }
  
      // get publishers
      if (is_array($entry->getPublishers())) {
        foreach ($entry->getPublishers() as $publisher) {
          $book->publishers[] = $publisher->getText(); 
        }
      }
      
      // get publication date
      if (is_array($entry->getDates())) {
        $arr = $entry->getDates();
        $book->pubdate = (is_object($arr[0])) ? 
         $arr[0]->getText() : 'Unspecified'; 
      }
  
      // get ISBN numbers
      if (is_array($entry->getIdentifiers())) {
        foreach ($entry->getIdentifiers() as $id) {
          if (preg_match('/ISBN/', $id->getText())) {
            $book->isbn[] = $id->getText(); 
          }  
        }
      }
      
      // get first subject
      if (is_array($entry->getSubjects())) {
        $arr = $entry->getSubjects();
        $book->subject = is_object($arr[0]) ? 
         $arr[0]->getText() : 'Unspecified'; 
      }
      
      // get first description
      if (is_array($entry->getDescriptions())) {
        $arr = $entry->getDescriptions();
        $book->desc = is_object($arr[0]) ? 
         $arr[0]->getText() : 'No description available'; 
      }    
      ?>
      
        <div class="entry">
          <div class="thumbnail">
            <img src="<?php echo ($entry->getThumbnailLink()) ? 
             $entry->getThumbnailLink()->getHref() : ''; ?>" />      
          </div>
          <div class="data">
          <?php echo $x; ?>. <?php echo ucwords(@implode(': ', 
           $book->titles)); ?><br/>
          <?php echo @implode(', ', $book->authors); ?> |
          <?php echo @implode(', ', $book->publishers); ?> |
          <?php echo $book->subject; ?> |
          <?php echo date('d M Y', strtotime($book->pubdate)); ?> <br/>
            <span class="desc"><?php echo $book->desc; ?></span> 
            <br/>
            <span class="small"><?php echo @implode(', ', $book->isbn); ?> |       
              Added to library on: <?php echo ($entry->getPublished()) ? 
              date('d M Y', strtotime($entry->getPublished()->getText())) : ''; 
              ?> | 
              <a href="<?php echo $entry->getInfoLink()->getHref(); ?>"
               >More information</a>  
            </span>
          </div>
        </div>      
        <?php $x++; ?>
      <?php endforeach; ?>
    <?php endif; ?>
    
  </body>
</html>
getUserLibraryFeed()

图8展示了一个结果示例:

图8.对用户的图书馆提要的Google Books API请求的结果

将书籍添加到用户库

这样就可以检索用户库的内容了……但是如何在其中添加新标题呢? 使用Google图书搜索数据API,您只需将包含图书唯一卷标识符的XML编码的发布到用户的图书馆供稿中。 清单7给出了一个这样的POST请求的示例:

清单7:向书库添加书到用户的示例POST请求
POST /books/feeds/users/me/collections/library/volumes HTTP/1.1
Host: books.google.com
Connection: close
User-Agent: MyCompany-MyApp-1.0 Zend_Framework_Gdata/1.9.0
authorization: GoogleLogin 
Content-Type: application/atom+xml
Accept-encoding: identity
Content-Length: 97

<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
  <atom:id>BOOK_VOLUME_ID_HERE</atom:id>
</atom:entry>
insertVolume()
清单8:将书籍添加到用户的图书馆
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Books');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');

// set credentials for ClientLogin authentication
$user = "[email protected]";
$pass = "secret";

try {
  // perform login 
  $client = Zend_Gdata_ClientLogin::getHttpClient(
    $user, $pass, 'print');
  $books = new Zend_Gdata_Books($client);

  // add book to user's library using volume ID
  $id = 'BOOK_VOLUME_ID_HERE';
  $entry = new Zend_Gdata_Books_VolumeEntry();
  $entry->setId(new Zend_Gdata_App_Extension_Id($id));
  $books->insertVolume(
      $entry,
      Zend_Gdata_Books::MY_LIBRARY_FEED_URI
  );
    
  // display success message
  echo "Volume added successfully with ID: $id";  
} catch (Exception $e) {
  die('ERROR:' . $e->getMessage());  
}
?>

添加书评和标签

<entry>

清单9给出了一个这样的POST请求的示例:

清单9:添加书评的示例POST请求
POST /books/feeds/users/me/volumes HTTP/1.1
Host: www.google.com
Connection: close
User-Agent: MyCompany-MyApp-1.0 Zend_Framework_Gdata/1.9.0
authorization: GoogleLogin 
Accept-encoding: identity
Content-Type: application/atom+xml
Content-Length: 3291

<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
  <openAccess xmlns="http://schemas.google.com/books/2008" 
   value="http://schemas.google.com/books/2008#disabled"/>
  <atom:category term="http://schemas.google.com/books/2008#volume" 
   scheme="http://schemas.google.com/g/2005#kind"/>
  <atom:id>http://www.google.com/books/feeds/volumes/BOOK_VOLUME_ID_HERE
   </atom:id>
  <atom:link href="http://bks7.books.google.com/books?id=BOOK_VOLUME_ID_HERE
   &printsec=frontcover&img=1&zoom=5&sig=ACfU3U0ayCK47roiq
   7r_hf_Iy-tQ&source=gbs_gdata" 
   rel="http://schemas.google.com/books/2008/thumbnail" type="image/x-unknown"/>
  <atom:link href="http://books.google.com/books?id=BOOK_VOLUME_ID_HERE
   &ie=ISO-8859-1&source=gbs_gdata" 
   rel="http://schemas.google.com/books/2008/info" type="text/html"/>
  <atom:link href="http://www.google.com/books/feeds/users/me/volumes" 
   rel="http://schemas.google.com/books/2008/annotation" 
   type="application/atom+xml"/>
  <atom:link href="http://books.google.com/books?id=BOOK_VOLUME_ID_HERE
   &ie=ISO-8859-1" rel="alternate" type="text/html"/>
  <atom:link href="http://www.google.com/books/feeds/volumes/BOOK_VOLUME_ID_HERE" 
   rel="self" type="application/atom+xml"/>
  <atom:title type="text">The Two Minute Rule</atom:title>
  <atom:updated>2009-12-28T10:15:44.000Z</atom:updated>
  <dc:creator xmlns:dc="http://purl.org/dc/terms">Robert Crais</dc:creator>
  <dc:date xmlns:dc="http://purl.org/dc/terms">2006-01-01</dc:date>
  <dc:format xmlns:dc="http://purl.org/dc/terms">Dimensions 10.8x17.2x3.0 cm
  </dc:format>
  <dc:format xmlns:dc="http://purl.org/dc/terms">465 pages</dc:format>
  <dc:format xmlns:dc="http://purl.org/dc/terms">book</dc:format>
  <dc:identifier xmlns:dc="http://purl.org/dc/terms">BOOK_VOLUME_ID_HERE
  </dc:identifier>
  <dc:identifier xmlns:dc="http://purl.org/dc/terms">ISBN:1111111111
  </dc:identifier>
  <dc:identifier xmlns:dc="http://purl.org/dc/terms">ISBN:1111111111111
  </dc:identifier>
  <dc:language xmlns:dc="http://purl.org/dc/terms">en</dc:language>
  <dc:publisher xmlns:dc="http://purl.org/dc/terms">Pocket Books
  </dc:publisher>
  <dc:subject xmlns:dc="http://purl.org/dc/terms">Fiction / Action & Adventure
  </dc:subject>
  <dc:subject xmlns:dc="http://purl.org/dc/terms">Fiction / Suspense
  </dc:subject>
  <dc:subject xmlns:dc="http://purl.org/dc/terms">Fiction / Action & Adventure
  </dc:subject>
  <dc:title xmlns:dc="http://purl.org/dc/terms">The Two Minute Rule
  </dc:title>
  <gbs:embeddability xmlns:gbs="http://schemas.google.com/books/2008" 
   value="http://schemas.google.com/books/2008#not_embeddable"/>
  <gd:rating xmlns:gd="http://schemas.google.com/g/2005" min="1" max="5" 
   average="4.20"/>
  <gbs:review xmlns:gbs="http://schemas.google.com/books/2008">
   This book is amazing - v!</gbs:review>
  <gbs:viewability xmlns:gbs="http://schemas.google.com/books/2008" 
   value="http://schemas.google.com/books/2008#view_no_pages"/>
</atom:entry>

清单10给出了使用目标书的卷标识符和Zend_Gdata库发布评论的示例:

清单10:添加书评
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Books');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');

// set credentials for ClientLogin authentication
$user = "[email protected]";
$pass = "secret";

try {
  // perform login 
  $client = Zend_Gdata_ClientLogin::getHttpClient(
    $user, $pass, 'print');
  $books = new Zend_Gdata_Books($client);

  // add review to book
  $id = 'BOOK_VOLUME_ID_HERE';  
  $entry = $books->getVolumeEntry($id);
  $review = new Zend_Gdata_Books_Extension_Review();
  $review->setText("This book is amazing - v!");
  $entry->setReview($review);  
  $books->insertVolume(
      $entry,
      $entry->getAnnotationLink()->getHref()
  );  
  
  // display success message
  echo "Review successfully added with ID: $id";  
} catch (Exception $e) {
  die('ERROR:' . $e->getMessage());  
}
?>
getVolumeEntry()setReview()insertVolume()

同样,Google图书搜索还允许用户使用描述性关键字标记或“标记”每本书。 这是一项有用的社区功能,可以产生更有效和相关的搜索结果。 清单11给出了一个示例,说明如何以编程方式将这些标签附加到书籍条目:

清单11:添加书籍标签
<?php
// load Zend Gdata libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Books');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');

// set credentials for ClientLogin authentication
$user = "[email protected]";
$pass = "secret";

try {
  // perform login 
  $client = Zend_Gdata_ClientLogin::getHttpClient(
    $user, $pass, 'print');
  $books = new Zend_Gdata_Books($client);

  // add labels to book
  $id = 'BOOK_VOLUME_ID_HERE';  
  $entry = $books->getVolumeEntry($id);
  $entry->setCategory(array(
    new Zend_Gdata_App_Extension_Category('crime', 
      'http://schemas.google.com/books/2008/labels'),
    new Zend_Gdata_App_Extension_Category('suspense', 
      'http://schemas.google.com/books/2008/labels'),
    new Zend_Gdata_App_Extension_Category('elvis cole', 
      'http://schemas.google.com/books/2008/labels')
  ));  
  $books->insertVolume(
      $entry,
      $entry->getAnnotationLink()->getHref()
  );  
  
  // display success message
  echo "Labels successfully added for ID: $id";  
} catch (Exception $e) {
  die('ERROR:' . $e->getMessage());  
}
?>
setCategory()insertVolume()

添加到Google图书搜索的评论和标签不是私人的,并且可以通过Google图书网站或公共供稿URL对所有Internet用户可见。 为了说明这一点,请考虑您可以通过访问位于URL http://books.google.com/books/feeds/users/USER_ID/volumes的用户注释供稿来查看特定用户创建的所有评论和标签。 请注意,此URL中的USER_ID必须是用户在Google图书搜索中的唯一标识号,而不是其Google帐户用户名。 您可以在用户的​​“我的图书馆” URL链接中找到该用户的Google图书搜索标识号。

结论

Google图书搜索数据API尽管仍在开发中,但在允许开发人员将图书搜索结果集成到Web应用程序中方面具有巨大的潜力。 本文中的示例向您介绍了Google图书搜索批量供稿; 向您展示了如何按关键字,作者和标题搜索视频; 并说明了如何从搜索结果供稿中提取图书元数据,包括出版商和作者信息,缩略图和ISBN号。 它还为您提供了Google图书搜索社区功能的速成课程,说明了如何以编程方式向书条目添加评论和标签。

正如这些示例所证明的,在创建新的Web应用程序时,Google图书搜索REST API为开发人员提供了极大的灵活性和自由度。 如果您要尝试将图书搜索数据与其他Web服务中的数据融合在一起,或者只是为作者,出版商或消费者构建自定义的搜索界面,这将非常有用。 有时玩,看看你的想法!

翻译自: https://www.ibm.com/developerworks/web/library/x-gbookapi/index.html

上传应用程序到谷歌商店