上传应用程序到谷歌商店

如果您以任何方式与出版业建立联系,或者即使您只是一个狂热的读者,那么您都有可能听说过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提要组成。

典型的“书籍搜索”供稿包含的信息多于构建有用且相关的应用程序的信息。 要亲自查看,请尝试在您喜欢的网络浏览器中访问URL http://books.google.com/books/feeds/volumes?q=php。 此REST方法返回与关键字php相匹配的书籍列表。 对这种方法的原始XML响应(可以在结果页面的源代码中查看)包含这些书的详细信息,可能类似于清单1 :

清单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>

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

  • Google图书搜索数据API使用包含请求数据的Atom提要来响应REST请求。 在大多数情况下,最外面的<feed>元素包含<link>元素和<openSearch:>元素,其中<link>元素包含结果集的当前,下一页和前一页的URL,而<openSearch:>元素包含搜索的摘要统计信息。
  • 最外面的<feed>元素包含一个或多个<entry>元素,每个元素代表与搜索查询匹配的一本书或一本书。 每个<entry>包含有关其代表的书籍的更多信息,包括标题,描述,出版日期,作者和出版商。 每个<entry>还包含<link>元素,这些元素提供指向详细图书信息,缩略图,预览(如果可用)以及注释(例如评论和评分)的URL链接。
  • 每个条目中的<dc:>命名空间元素都应特别提及。 这些元素对应于都柏林核心元数据计划(DCMI)的元素,该计划为简单的信息标记和访问提供了一组标准的可重用定义。 如清单1所示,这些元素包含有关每本书的标题,作者,出版商,格式,主题和ISBN标识符的信息。

并非所有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 = "xxx@gmail.com";
$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()方法,该方法返回与搜索查询匹配的书籍标题的提要。 该方法将传递一个已配置的Zend_Gdata_Books_VolumeQuery类的实例,并通过setQuery()类方法设置查询字符串。 对getVolumeFeed()方法的响应是一个Atom提要,类似于清单1中所示的提要。 该提要将被自动解析并转换为Zend_Gdata_Books_VolumeEntry对象的数组,每个对象代表提要中的一个<entry> 。 现在,遍历此数组,使用对象属性检索每个条目的详细信息并将其转换为HTML页面,这很简单。

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

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

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

清单3:检索与用户提供的关键字匹配的搜索结果
<?php
if (isset($_POST['submit'])) {// load Zend Gdata librariesrequire_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 = "xxx@gmail.com";$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搜索的结果

您会在清单3中注意到一个附加功能: Zend_Gdata_Books_VolumeEntry::getInfoLink()方法的使用,该方法返回指向Google图书搜索网站上的图书信息页面的链接。 单击此链接会将用户重定向到一个页面,该页面除其他外,其中包含详细的书籍说明和用户评论。 图3给出了一个这样的页面的示例:

图3.书籍详细信息页面

还需要指出的是,传递给Google图书搜索数据API的查询字符串必须是URL编码的字符串。 您会发现,在前面的两个清单中,都是使用PHP的urlencode()方法完成的。

检索详细的图书信息

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

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

清单4:检索书籍详细信息
<?php
if (isset($_POST['submit'])) {// load Zend Gdata librariesrequire_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 = "xxx@gmail.com";$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 titleif (is_array($entry->getTitles())) {foreach ($entry->getTitles() as $title) {$book->titles[] = $title->getText(); }}// get authorsif (is_array($entry->getCreators())) {foreach ($entry->getCreators() as $creator) {$book->authors[] = $creator->getText(); }}// get publishersif (is_array($entry->getPublishers())) {foreach ($entry->getPublishers() as $publisher) {$book->publishers[] = $publisher->getText(); }}// get publication dateif (is_array($entry->getDates())) {$arr = $entry->getDates();$book->pubdate = (is_object($arr[0])) ? $arr[0]->getText() : 'Unspecified'; }// get ISBN numbersif (is_array($entry->getIdentifiers())) {foreach ($entry->getIdentifiers() as $id) {if (preg_match('/ISBN/', $id->getText())) {$book->isbn[] = $id->getText(); }  }}// get first subjectif (is_array($entry->getSubjects())) {$arr = $entry->getSubjects();$book->subject = is_object($arr[0]) ? $arr[0]->getText() : 'Unspecified'; }// get first descriptionif (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()方法返回该书的ISBN-10和ISBN-13数字数组及其Google图书搜索记录ID
  • getThumbnailLink()方法将URL返回到书籍封面的缩略图
  • getVolumeId()方法返回Google图书搜索服务中图书的唯一体积标识符。

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

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

使用查询过滤器

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

  • start-index参数,用于指定提要中条目的起始偏移量
  • max-results参数,用于指定提要中的条目数
  • min-viewability参数,该参数指定供稿条目是否仅包括存在部分或完整预览的那些书

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

清单5:按作者,标题和可见性过滤搜索结果
<?php
if (isset($_POST['submit'])) {// load Zend Gdata librariesrequire_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 = "xxx@gmail.com";$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 titleif (is_array($entry->getTitles())) {foreach ($entry->getTitles() as $title) {$book->titles[] = $title->getText(); }}// get authorsif (is_array($entry->getCreators())) {foreach ($entry->getCreators() as $creator) {$book->authors[] = $creator->getText(); }}// get publishersif (is_array($entry->getPublishers())) {foreach ($entry->getPublishers() as $publisher) {$book->publishers[] = $publisher->getText(); }}// get publication dateif (is_array($entry->getDates())) {$arr = $entry->getDates();$book->pubdate = (is_object($arr[0])) ? $arr[0]->getText() : 'Unspecified'; }// get ISBN numbersif (is_array($entry->getIdentifiers())) {foreach ($entry->getIdentifiers() as $id) {if (preg_match('/ISBN/', $id->getText())) {$book->isbn[] = $id->getText(); }  }}// get first subjectif (is_array($entry->getSubjects())) {$arr = $entry->getSubjects();$book->subject = is_object($arr[0]) ? $arr[0]->getText() : 'Unspecified'; }// get first descriptionif (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的此修订版中,向用户显示了标题,作者和可见性的单独搜索字段。 根据收到的输入,将使用适当的修饰符构造搜索查询,并将其传输到Google图书搜索API。 注意setMinViewability()setMaxResults()方法,它们为min-viewabilitymax-results输入参数提供了一个面向对象的接口。

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

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

访问用户库

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

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

图7. Google图书网站上的用户库

经过身份验证的用户库的内容也可以作为Atom提要获得,适用于在PHP应用程序中进行解析。 类似于清单1中描述的批量供稿,此供稿包含一组<entry>元素,每个元素代表用户库中的一本书。 可以通过Zend_Gdata_Books对象的getUserLibraryFeed()方法将该提要解析为一组PHP对象,然后将其用于生成库HTML视图。 清单6展示了:

清单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 = "xxx@gmail.com";
$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 titleif (is_array($entry->getTitles())) {foreach ($entry->getTitles() as $title) {$book->titles[] = $title->getText(); }}// get authorsif (is_array($entry->getCreators())) {foreach ($entry->getCreators() as $creator) {$book->authors[] = $creator->getText(); }}// get publishersif (is_array($entry->getPublishers())) {foreach ($entry->getPublishers() as $publisher) {$book->publishers[] = $publisher->getText(); }}// get publication dateif (is_array($entry->getDates())) {$arr = $entry->getDates();$book->pubdate = (is_object($arr[0])) ? $arr[0]->getText() : 'Unspecified'; }// get ISBN numbersif (is_array($entry->getIdentifiers())) {foreach ($entry->getIdentifiers() as $id) {if (preg_match('/ISBN/', $id->getText())) {$book->isbn[] = $id->getText(); }  }}// get first subjectif (is_array($entry->getSubjects())) {$arr = $entry->getSubjects();$book->subject = is_object($arr[0]) ? $arr[0]->getText() : 'Unspecified'; }// get first descriptionif (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>

您应该从本文前面的部分中熟悉其中的大多数内容。 该脚本会打开与Google图书搜索服务的经过身份验证的连接,初始化Zend_Gdata_Books对象,并使用getUserLibraryFeed()方法检索包含用户库中书籍列表的供稿。 此提要表示为一个PHP对象数组,现在可以很轻松地遍历该数组,处理每个条目并使用适当HTML标记显示结果。

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

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

将书籍添加到用户库

这样就可以检索用户库的内容了……但是如何在其中添加新标题呢? 使用Google图书搜索数据API,您只需将包含图书唯一卷标识符的XML编码的<entry>发布到用户的图书馆供稿中。 清单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>

要使用Zend_Gdata_Books完成相同的任务,请初始化一个新的Zend_Gdata_Books_VolumeEntry对象,为其分配卷标识符,然后使用insertVolume()方法将其附加到用户的库提要中。 清单8演示了代码:

清单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 = "xxx@gmail.com";
$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 messageecho "Volume added successfully with ID: $id";
} catch (Exception $e) {die('ERROR:' . $e->getMessage());
}
?>

添加书评和标签

除了允许用户将书添加到他们的图书馆外,G​​oogle图书搜索API还允许他们向书添加评论和标签。 评论和标签存储为Google所说的“注释”,如果您回顾清单1 ,您会发现每个条目都包含一个注释URL。 因此,要将评论或标签添加到书中,您只需要为书创建XML编码的<entry> ,将评论和/或标签附加到此条目,然后将整个内容发布到书的注释URL 。

清单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=ACfU3U0ayCK47roiq7r_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 = "xxx@gmail.com";
$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 messageecho "Review successfully added with ID: $id";
} catch (Exception $e) {die('ERROR:' . $e->getMessage());
}
?>

在清单10中 , getVolumeEntry()方法用于使用其卷标识符检索书籍的当前条目,然后通过setReview()方法将包含审阅文本的Zend_Gdata_Books_Extension_Review对象附加到该条目。 然后, insertVolume()方法负责创建POST请求并更新Google服务器上的条目。

同样,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 = "xxx@gmail.com";
$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 messageecho "Labels successfully added for ID: $id";
} catch (Exception $e) {die('ERROR:' . $e->getMessage());
}
?>

在清单11中 ,每个标签都表示为Zend_Gdata_App_Extension_Category实例,然后使用setCategory()方法将这些实例附加到书本条目。 然后,调用insertVolume()方法将标签添加到Google图书搜索数据库中的图书条目中。

添加到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/opensource/library/x-gbookapi/index.html

上传应用程序到谷歌商店

上传应用程序到谷歌商店_将Google图书搜索集成到PHP应用程序中相关推荐

  1. Office文档上传后实时转换为PDF格式_图片文件上传后实时裁剪_实现在线预览Office文档

    Office文档上传后实时转换为PDF格式_图片文件上传后实时裁剪 前置条件 安装LibreOffice 安装OpenOffice 安装Unoconv 安装ImageMagick.x86_64 安装G ...

  2. 阿里iconfont上传svg图片空白、或展示不全的解决方案/搜索到的icon无法改变颜色解决方案

    问题1:阿里iconfont上传svg图片空白.或展示不全 原因 造成这个问题的原因,可能是因为sketch.dx等软件在导出svg时,自动在svg上添加了一些iconfont平台无法解析的属性造成的 ...

  3. layui图片上传按钮按着没反应_关于layui动态生成文件上传按钮后点击无效的解决办法...

    首先,这是一个坑,大坑,网上一大堆写的云里雾里,不知所以,转了一圈,除了copy就是copy,Jesus God,花了一晚上,走通了这个坑,话不多说,直接解决 layui版本: layui-v2.5. ...

  4. 如何提高本地文件上传至百度云的速度_【软件推荐】满速下载软件,说出来你可能不信最高速度达到150m/s...

    百度云限速一直是令百度云用户非常头疼的问题,有时候即使开了会员也不一定有太大的改善,看着10~200kb/s的下载速度,再看看需要的时间是不是很发愁,那么今天我们来打破这个规则,规则就是用来打破的. ...

  5. uni-app - 头像图片裁剪组件(支持多种裁剪,手势控制旋转或缩放、内外部控制图片移动、提供上传后端接口方案、头像图片美化)全端完美兼容 H5 App 小程序,最好用的图片上传后裁剪插件教程源代码

    前言 网上的教程代码非常乱且都有 BUG 存在,非常难移植到自己的项目中,而且很难. 实现了 完美兼容 H5 App 小程序,选取手机本地相册或拍照,图片上传裁切内置多种方案,样式随便改, 本文代码干 ...

  6. Chrome扩展:本地应用上传本地文件到谷歌插件,再由插件上传到服务器

    须知 谷歌扩展只能传输和JSON兼容的数据,可通过JSON.parse(JSON.stringify(form_data))判断兼容与否. 解决方案 FormData和JSON不兼容.要上传文件,可通 ...

  7. 上传失败 已保存至草稿_特大福利 清睿口语100成都会议专家讲座视频已上传至口语100网站...

    点击「口语100网络学习空间」可快速关注 清睿口语100成都会议(即第三届全国中小学英语学科教学与信息化教育深度融合高级研讨会)专家讲座视频已上传至口语100网站,进入网站即可观看学习. 观看方式: ...

  8. 上传失败 已保存至草稿_学霸的草稿纸火了,卷面整洁,网友调侃:作业都比不上这草稿本...

    文章原创,版权归本作者所有,欢迎个人转发分享! 学霸和学渣的区别,从很多方面能考究出来,听课时的专心程度,写作业时的细心程度,以及草稿纸的工整程度.相比随意应付,井井有条,才是学霸的正确打开方式. 学 ...

  9. okhttp上传图片和其他参数_Android中Okhttp3实现上传多张图片同时传递参数_放手_前端开发者...

    之前上传图片都是直接将图片转化为io流传给服务器,没有用框架传图片. 最近做项目,打算换个方法上传图片. Android发展到现在,Okhttp显得越来越重要,所以,这次我选择用Okhttp上传图片. ...

最新文章

  1. Silverlight游戏设计(Game Design):目录
  2. jre,jdk,jvm的关系
  3. [Python]元组与列表的区别及内建用法
  4. ViewPager页面切换效果
  5. 3线程的终止方式,线程属性,NPTL
  6. docker(iptables)目标地址转换,运行中的容器映射端口
  7. windows编程函数(一)
  8. com+ system application 启动_[jvmsandboxrepeater 学习笔记][入门使用篇] 1 安装与启动
  9. Java EE互联网轻量级框架整合开发
  10. 多重网格、自适应网格和无网格
  11. Java全栈开发---Java ERP系统开发:商业ERP(七
  12. 导出oracle数据库日志文件,Oracle数据库导出还原的两种基本方法imp/impdp
  13. 完全兼容ADI的ADM2582E/ADM2587E的(MORNSUN)TD(H)541S485H
  14. 21秋期末考试建设工程法规10221k1
  15. 我再copy回来。中海真是有心人。只是,你们在哪里?
  16. 个人搭建ASP网站,从头开始完全教程(一)
  17. 开源护眼工具LightBulb2.3.3汉化说明
  18. シェリーヌ / 老师
  19. 你不知道的JS 沙箱隔离
  20. 天馈线测试仪 如何选择

热门文章

  1. 汇编语言定义变量c,汇编c语言变量
  2. qt不能输入中文的解决办法
  3. 微信支付 APP端 后端 第一弹 微信下单
  4. [附源码]SSM计算机毕业设计网上点餐系统JAVA
  5. 【高级数据结构】红黑树
  6. php微信点赞接口文档,聊天接口说明
  7. 【uniapp】跳转 navigateTo 页面跳转路径有层级限制,不能无限制跳转新页面 解决方法
  8. python keyshot_KeyShot 7 非常好用的3D渲染软件
  9. 【光学】基于matlab模拟拉盖尔高斯【含Matlab源码 2167期】
  10. 防范保险企业内部风险,原点安全出席中国寿险财险科技应用高峰论坛