標籤:c#網路編程 豆瓣api httpwebrequest httpwebresponse 解析xml
這篇文章主要是講述如何通過豆瓣API擷取書籍的資訊,起初看到這個內容我最初的想法是在"C# 網路編程之網頁簡單下載實現"中通過HttpWebResponse類下載源碼,再通過Regex分析擷取結點標籤得到資訊.但後來發現可以通過豆瓣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; //HTTPusing System.IO; //檔案 流操作using System.Text.RegularExpressions; //Regexusing 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