C# 網路編程之通過豆瓣API擷取書籍資訊(一)

來源:互聯網
上載者:User

標籤: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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.