C# 网络编程之通过豆瓣API获取书籍信息

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
OpenSearch LLM智能问答版免费试用套餐,存储1GB首月+计算资源100CU
简介:

这篇文章主要是讲述如何通过豆瓣API获取书籍的信息,起初看到这个内容我最初的想法是在"C# 网络编程之网页简单下载实现"中通过HttpWebResponse类下载源码,再通过正则表达式分析获取结点标签得到信息.但后来发现可以通过豆瓣API提供的编程接口实现.
该文章仅是基础性C#网络编程文章,尝试测试了下豆瓣API,并没什么高深的内容.但希望对大家有所帮助,仅供学习.
(警告:文章仅供参考,提供一种想法,否则访问多次-10次被403 forbidden莫怪.建议认证使用豆瓣API)

一.豆瓣API介绍

在开发之前你需要申请创建一个应用,从而获取一个新的API Key(唯一标识你的Connect站点和API使用者).
正如豆瓣API快速入门(
http://www.douban.com/service/apidoc/guide)中例子:这个示例中展示了使用API获得ID为1220562的书的信息, 请求的url如下(注意将{yourapikey}替换为你的API Key).
http://api.douban.com/book/subject/1220562?apikey={yourkeyapi}
返回的XML文档如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:db="http://www.douban.com/xmlns/" 
xmlns:gd="http://schemas.google.com/g/2005" 
xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" 
xmlns:opensearch="http://a9.com/-/spec/opensearchrss/1.0/">
	<id>http://api.douban.com/book/subject/1220562</id>
	<title>满月之夜白鲸现</title>
	<category scheme="http://www.douban.com/2007#kind" term="http://www.douban.com/2007#book"/>
	<author>
		<name>[日] 片山恭一</name>
	</author>
	<link href="http://api.douban.com/book/subject/1220562" rel="self"/>
	<link href="http://book.douban.com/subject/1220562/" rel="alternate"/>
	<link href="http://img3.douban.com/spic/s1747553.jpg" rel="image"/>
	<link href="http://m.douban.com/book/subject/1220562/" rel="mobile"/>
	<summary>那一年,是听莫扎特、钓鲈鱼和家庭破裂的一年。说到家庭破裂,母亲怪自己当初没有找到好男人,父亲则认为当时是被狐狸精迷住了眼,失常的是母亲,但出问题的是父亲……。</summary>
	<db:attribute name="isbn10">7543632608</db:attribute>
	<db:attribute name="isbn13">9787543632608</db:attribute>
	<db:attribute name="title">满月之夜白鲸现</db:attribute>
	<db:attribute name="pages">180</db:attribute>
	<db:attribute name="translator">豫人</db:attribute>
	<db:attribute name="author">[日] 片山恭一</db:attribute>
	<db:attribute name="price">15.00元</db:attribute>
	<db:attribute name="publisher">青岛出版社</db:attribute>
	<db:attribute name="binding">平装</db:attribute>
	<db:attribute name="pubdate">2005-1</db:attribute>
	<db:tag count="125" name="片山恭一"/>
	<db:tag count="59" name="日本"/>
	<db:tag count="53" name="日本文学"/>
	<db:tag count="36" name="小说"/>
	<db:tag count="31" name="满月之夜白鲸现"/>
	<db:tag count="14" name="爱情"/>
	<db:tag count="8" name="純愛"/>
	<db:tag count="8" name="外国文学"/>
	<gd:rating average="7.0" max="10" min="0" numRaters="322"/>
</entry>

此时,我需要做的就是通过输入的URL获取返回的XML中的数据,通过HttpWebRequest和HttpWebResponse获取HTTP请求和应答,并解析XML中的信息(较难).后来我才发现如果想试验下API,豆瓣是允许在不申请API Key情况下进行API调用(每分钟请求不超过10次).也就是说我在程序中输入网址如下即可返回XML.
http://api.douban.com/book/subject/1220562

二.C#获取豆瓣书籍信息

1.添加命名空间

using System.Net;                      //HTTP
using System.IO;                       //文件 流操作
using System.Text.RegularExpressions;  //正则表达式
using System.Xml;                      //Xml文档

2.添加按钮点击事件

//点击按钮"获取信息"
private void button1_Click(object sender, EventArgs e)
{
    richTextBox1.Clear();
    //获取输入的URL
    string url = textBox1.Text.ToString();
    //HttpWebRequest对象实例:该类用于获取和操作HTTP请求 创建WebRequest对象
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    //HttpWebResponse对象实例:该类用于获取和操作HTTP应答 
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    //构造字节流
    StreamReader reader = new StreamReader(response.GetResponseStream());
    //流从头读至尾
    string xmlUrl = reader.ReadToEnd();
    reader.Close();
    response.Close();
    //调用自定义函数获取XML信息
    GetInfoXML(xmlUrl);
}

3.自定义函数获取书籍信息

//获取豆瓣XML内容并显示
private void GetInfoXML(string xmlUrl)
{
    try
    {
        //实例Xml文档
        XmlDocument xmlDoc = new XmlDocument();
        //从指定字符串加载xml文档 
        xmlDoc.LoadXml(xmlUrl);                       
        //实例解析、加入并移除集合的命名空间及范围管理
        XmlNamespaceManager xmlNM = new XmlNamespaceManager(xmlDoc.NameTable);
        //将给定命名空间添加到集合 
        xmlNM.AddNamespace("db", "http://www.w3.org/2005/Atom");
        //获取文档根元素
        XmlElement root = xmlDoc.DocumentElement;
        //选择匹配Xpath(内容)表达式的结点列表 
        //函数原型:SelectNodes(string xpath,XmlNamespaceManger nsmgr)
        XmlNodeList nodes = root.SelectNodes("/db:entry", xmlNM);

        //获取子节点信息
        foreach (XmlNode nodeData in nodes)
        {
            foreach (XmlNode childnode in nodeData.ChildNodes)
            {
                string str = childnode.Name;
                switch (str)
                {
                    case "title":
                        string name = "标题名称:" + childnode.InnerText + "\r\n\r\n";
                        richTextBox1.AppendText(name);
                        break;                    
                    case "author":
                        string author = "作者:" + childnode.InnerText + "\r\n\r\n";
                        richTextBox1.AppendText(author);
                        break;
                    case "db:attribute":
                        { 
                            //获取<db:attribute name="XXX">的属性
                            switch (childnode.Attributes[0].Value)
                            {
                                case "pages":
                                    string pages="总页数:"+childnode.InnerText+"\r\n\r\n";
                                    richTextBox1.AppendText(pages);
                                    break;
                                case "price":
                                    string price="价格:"+childnode.InnerText+"\r\n\r\n";
                                    richTextBox1.AppendText(price);
                                    break;
                                case "publisher":
                                    string publisher="出版社:"+childnode.InnerText+"\r\n\r\n";
                                    richTextBox1.AppendText(publisher);
                                    break;
                                case "pubdate":
                                    string pubdate="出版日期:"+childnode.InnerText+"\r\n\r\n";
                                    richTextBox1.AppendText(pubdate);
                                    break;
                            }
                            break;
                        }
                    case "summary":                             
                        //显示内容 WordWrap设置为true自动换行(无需调用Split函数或求字符长度)
                        string summary="内容:"+childnode.InnerText+"\r\n\r\n";                                
                        richTextBox1.AppendText(summary);                             
                        break;
                    case "link":
                        //结点属性是Attributes[0]却失败,不能获取
                        if (childnode.Attributes[1].Value == "image")
                        {
                            //获取image路径 <link rel="image" href="http://xxx.jpg"/> 
                            string imagePath = childnode.Attributes[0].Value;
                            //下载图片
                            string imageName = "local.jpg";
                            System.Net.WebClient client = new System.Net.WebClient();
                            //下载指定URL资源到本地文件夹
                            //函数原型 DownloadFile(string address,string fileName)
                            client.DownloadFile(imagePath,imageName);
                            //从本地文件中加载图片
                            this.pictureBox1.Image = Image.FromFile(imageName);
                            //图像原图大小
                            this.pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
                            //下载第二张图片时总是出现"WebClient请求期间发生异常"
                        }
                        break;
                } //switch
            } //foreach
        } //foreach
    }
    catch (Exception msg) //异常处理
    {
        MessageBox.Show(msg.Message);
    }
} //GetInfoXML

4.运行结果如下


源网址中的书籍信息介绍如下图所示:

三.遇到的问题及总结

由上图可以发现我输入的网址没有包含API key也能获取,但我在测试时总是使用的.然后同时我也遇到了一些问题:
1.豆瓣API获取书籍信息接口,需要传subjectID或isbnID(国际标准书号),但我想实现的是只知道书名,就能获取书籍的信息,而不是仅仅传入一串URL,这些分析都让程序内容实现,这是接下来需要做的.
2.在使用WebClient和DownloadFile(string address,string fileName)下载图片时,当获取第二张图片总会提示错误"WebClient请求期间发生异常",不知道为啥,但不想使用stream或并发获取图片,仅想知道这是为啥?
3.这仅仅是一篇基础性的介绍使用豆瓣API的文章,目前豆瓣针对已经授权用户(开发API采用OAuth协议进行鉴权)可以实现很多功能,后面如果有时间可以写些“查看用户信息、用户友邻信息、增删改查用户收藏、查看评论”的文章.

最后希望该文章对大家有所帮助,如果文章中有错误或不足之处,还请海涵.同时文章也参考了一些资料,感谢这些作者.
(By:Eastmount 2014-5-2 下午3点 原创:http://blog.csdn.net/eastmount)
参考资料:
1.豆瓣API快速入门
http://www.douban.com/service/apidoc/guide
2.c#使用豆瓣API-sun8134
这里非常感谢该文章,在解析XML中我使用SelectSingleNodes方法失败后,参考了他的方法,也推荐大家去阅读
http://www.cnblogs.com/sun8134/archive/2010/12/15/1906879.html
3.豆瓣客户端-zh19900207 该文章仅有界面,但也是我想实现的功能描述
http://blog.csdn.net/zh19900207/article/details/8586000
4.XmlNode.SelectNodes 方法
http://msdn.microsoft.com/zh-cn/library/4bektfx9.aspx

相关实践学习
基于OpenSearch搭建高质量商品搜索服务
本场景主要介绍开放搜索(OpenSearch)打造独有的电商行业垂直解决方案,模板内置电商查询分析、排序表达式及行业算法能力,沉浸式体验更高性能和效果的智能搜索服务,助力企业在线业务智能增长。
相关文章
Cpp网络编程Winsock API
本文详细介绍了使用Winsock API进行C++网络编程的过程,通过具体实例实现了一个基于TCP协议的C/S架构通信demo。文章从服务端与客户端两方面展开,涵盖网络库初始化、套接字创建、绑定IP与端口、监听与连接、数据收发到关闭连接等关键步骤。重点解析了`WSAStartup`、`socket`、`bind`、`listen`、`accept`、`connect`、`send`和`recv`等函数的使用方法及注意事项,并对比了标准库与Winsock库在链接时的区别。适合初学者了解Winsock网络编程基础。
76 34
C# 一分钟浅谈:GraphQL API 与 C#
本文介绍了 GraphQL API 的基本概念及其优势,并通过 C# 实现了一个简单的 GraphQL 服务。GraphQL 是一种高效的 API 查询语言,允许客户端精确请求所需数据,减少不必要的数据传输。文章详细讲解了如何使用 `GraphQL.NET` 库在 C# 中创建和配置 GraphQL 服务,并提供了常见问题的解决方案和代码示例。
124 4
全球最新地震信息免费API接口教程
该接口提供全球最新地震信息,数据源自中国地震台网,每5分钟更新一次。支持POST/GET请求,需提供用户ID和KEY。返回数据包括地震等级、时间、经纬度、深度及位置等详细信息。示例请求和响应详见文档。
商品信息API接口的设计与实现
商品信息API接口的设计与实现,遵循RESTful原则以确保高效、可维护和良好的用户体验。API支持获取、查询、创建、更新和删除商品资源,URL模式直观易懂。请求参数通过查询字符串传递,支持分页和过滤。响应体结构化,包含数据、链接和元数据字段,便于解析。错误处理采用HTTP状态码结合JSON错误描述,提供明确反馈。
解锁电商数据的无限可能:探秘京东商品SKU信息API接口
京东商品SKU信息API接口是电商开发与运营中的重要工具,帮助开发者获取商品的详细属性,如库存、价格、规格等。通过该接口,电商平台可以丰富商品展示页面,提升用户体验;商家能实时掌握库存动态,优化销售策略;数据分析人员可深入洞察市场趋势,实现精准营销。使用前需注册京东开放平台账号、创建应用并获取API权限,同时仔细阅读API文档以确保正确调用。代码示例展示了如何用Python调用该接口,并处理返回数据。未来,该接口将在个性化推荐、智能库存管理和数据分析等领域发挥更大作用,助力电商业务创新与发展。
175 14
|
3月前
|
获取1688商品SKU信息API接口及实战应用
在电商蓬勃发展的今天,数据成为宝贵的财富。1688作为国内知名批发采购平台,提供商品SKU信息API接口,可获取库存、价格、规格等关键数据,助力电商运营、市场分析和价格监控。本文介绍如何注册1688开放平台账号、创建应用并获取AppKey/AppSecret,申请API权限,使用Python实现接口调用,处理响应数据,并注意请求频率限制和错误处理。通过该接口,可为电商运营和数据分析提供有力支持。
160 2
探秘淘宝商品SKU信息API接口
在电子商务中,SKU(库存量单位)用于区分商品的不同规格、颜色、尺寸等属性,是精细化管理的基础。本文深入探讨淘宝商品SKU信息API接口,介绍其功能特点、使用方法及应用场景,并提供Python代码示例。该API支持实时更新、多维度筛选,帮助开发者获取全面的SKU信息,优化库存管理、订单处理和销售数据分析,提升运营效率与市场竞争力。
206 1
深度探索淘宝详情API接口:高效获取商品信息的实践指南
淘宝详情API接口是阿里巴巴开放平台的重要组成部分,帮助开发者通过程序化方式获取淘宝商品的详细信息,如标题、价格、销量等。本文介绍其使用方法,涵盖权限申请、请求构造、异常处理及高级应用,助力开发者优化电商体验和业务决策。
【Azure Developer】Python代码调用Graph API将外部用户添加到组,结果无效,也无错误信息
根据Graph API文档,在单个请求中将多个成员添加到组时,Python代码示例中的`members@odata.bind`被错误写为`members@odata_bind`,导致用户未成功添加。
69 10
1688榜单商品详细信息API接口的开发、应用与收益
1688作为全球知名的B2B电商平台,为企业提供丰富的商品信息和交易机会。为满足企业对数据的需求,1688开发了榜单商品详细信息API接口,帮助企业批量获取商品详情,应用于信息采集、校验、同步与数据分析等领域,提升运营效率、优化库存管理、精准推荐、制定市场策略、降低采购成本并提高客户满意度。该接口通过HTTP请求调用,支持多种应用场景,助力企业在电商领域实现可持续发展。
132 4
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等