C# 網絡編程之通過豆瓣API獲取書籍信息
這篇文章主要是講述如何通過豆瓣API獲取書籍的信息,起初看到這個內容我最初的想法是在"C# 網絡編程之網頁簡單下載實現"中通過HttpWebResponse類下載源碼,再通過正則表達式分析獲取結點標簽得到信息.但後來發現可以通過豆瓣API提供的編程接口實現.
該文章僅是基礎性C#網絡編程文章,嚐試測試了下豆瓣API,並沒什麼高深的內容.但希望對大家有所幫助,僅供學習.
(警告:文章僅供參考,提供一種想法,否則訪問多次-10次被403 forbidden莫怪.建議認證使用豆瓣API)
一.豆瓣API介紹
在開發之前你需要申請創建一個應用,從而獲取一個新的API Key(唯一標識你的Connect站點和API使用者).
正如豆瓣API快速入門(https://www.douban.com/service/apidoc/guide)中例子:這個示例中展示了使用API獲得ID為1220562的書的信息, 請求的url如下(注意將{yourapikey}替換為你的API
Key).
https://api.douban.com/book/subject/1220562?apikey={yourkeyapi}
返回的XML文檔如下所示:
<?xml version="1.0" encoding="UTF-8"?> <entry xmlns="https://www.w3.org/2005/Atom" xmlns:db="https://www.douban.com/xmlns/" xmlns:gd="https://schemas.google.com/g/2005" xmlns:openSearch="https://a9.com/-/spec/opensearchrss/1.0/" xmlns:opensearch="https://a9.com/-/spec/opensearchrss/1.0/"> <id>https://api.douban.com/book/subject/1220562</id> <title>滿月之夜白鯨現</title> <category scheme="https://www.douban.com/2007#kind" term="https://www.douban.com/2007#book"/> <author> <name>[日] 片山恭一</name> </author> <link href="https://api.douban.com/book/subject/1220562" rel="self"/> <link href="https://book.douban.com/subject/1220562/" rel="alternate"/> <link href="https://img3.douban.com/spic/s1747553.jpg" rel="image"/> <link href="https://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.
https://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", "https://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="https://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點 原創:https://blog.csdn.net/eastmount)
參考資料:
1.豆瓣API快速入門
https://www.douban.com/service/apidoc/guide
2.c#使用豆瓣API-sun8134
這裏非常感謝該文章,在解析XML中我使用SelectSingleNodes方法失敗後,參考了他的方法,也推薦大家去閱讀
https://www.cnblogs.com/sun8134/archive/2010/12/15/1906879.html
3.豆瓣客戶端-zh19900207 該文章僅有界麵,但也是我想實現的功能描述
https://blog.csdn.net/zh19900207/article/details/8586000
4.XmlNode.SelectNodes 方法
https://msdn.microsoft.com/zh-cn/library/4bektfx9.aspx
最後更新:2017-04-03 12:56:30