關于HTML解析 For IOS

最近公司有一個需求,需要從某網頁上獲取一些數據傳給后臺。那就是通過固定網址下載html網頁源代碼,然后解析。

我先說下解析的庫是Ono,他的作者是mattt,也是AFNetworking的貢獻者。

Ono非常小,如果是不用CocoaPods添加的話也只需加入ONOXMLDocument.h和ONOXMLDocument.m兩個文件就好了,不過還要導入libxml2系統自帶的庫,在Build Setting-Header Search Paths中加入 "/usr/include/libxml2"路徑。(后有截圖)

當然如果使用CocoaPods的話就:
pod 'Ono'

Ono庫可以單獨使用也可以配合AFNetworking一起用。

解析完整過程

這里的url是中國商品信息服務平臺的查詢接口。

首先獲取html:

NSString *urlstring = [NSString stringWithFormat:@"http://search.anccnet.com/searchResult2.aspx?keyword=%@",string];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlstring] options:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000) error:nil];

url中的string是商品條形碼的數字(當然也可以是商品名)。
CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000) 這是網頁的編碼格式,一般中國網站的編碼格式都是gb2312,當然這也能在html頭信息中看到(下面會講到)。

具體內容你可以用chrome、firefox等瀏覽器打開看下源代碼。你也可以用:

NSString *appConnect = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlstring] encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000) error:nil];

然后輸出字符串查看具體內容。因為內容較多,我就把需要中到的內容展示出來(不需要的內容我刪掉了):

<!DOCTYPE html>
<html>
<head>
<meta charset="gb2312" />
    </head>
    <body >
    <form name="form1" method="post" action="searchResult2.aspx?keyword=6949322340125" id="form1">
      <div class="wrap">
        <div class="bodyer">
          <div class="mainly">
              <div id="outter">
                <ol id="results">
                  
                      <li>
                        <div class="result">
                          <p class="p-img" align="center"><a id="repList_ctl00_herl" target="_blank"> ![](/img/empty_90-90.8.png)</a></p>
                          <dl class="p-supplier">
                            <dt>商標:</dt>
                            <dd>惠松</dd>
                            <dt>發布廠家:</dt>
                            <dd>
                              <a id="repList_ctl00_firmLink" target="_blank">浙江惠松制藥有限公司</a>
                            </dd>
                          </dl>
                          <dl class="p-info">
                            <dt>商品條碼:</dt>
                            <dd><a  target="_blank">06949322340125</a></dd>
                            <dt>名稱:</dt>
                            <dd> 復方魚腥草合劑</dd>
                            <dt>規格型號:</dt>
                            <dd> 10ML12憑</dd>
                            <dt>描述:</dt>
                            <dd> </dd>
                          </dl>
                          <br clear="all" />
                        </div>
                      </li>        
                </ol>
              </div>
            </div>
            <div id="myPager">

</div>
          </div>
          
        </div>

</html>

html的內容我就不解釋了,可以在w3school 中查看。
可以看到頭部中有顯示是gb2312編碼格式。我要獲取到的就是其中商品的一些信息(包括商品條碼、名稱、規格型號、描述、商標和發布廠商)。

下面是解析的代碼:

ONOXMLDocument *document = [ONOXMLDocument HTMLDocumentWithData:data error:nil];
HTMLMedicine *medicine = [[HTMLMedicine alloc] init];
NSString *xpath = @"http://body/form/div[@class='wrap']/div[@class='bodyer']/div[@class='mainly']/div[@id='outter']/ol[@id='results']/li[1]/div[@class='result']";
[document enumerateElementsWithXPath:xpath usingBlock:^(ONOXMLElement *element, NSUInteger idx, BOOL *stop) {
        NSLog(@"%@: %@", element.tag, element.attributes);
        
        for (ONOXMLElement *celement in element.children) {
            
            //商家和發布廠家
            if ([celement.tag isEqualToString:@"dl"] && [celement.attributes[@"class"] isEqualToString:@"p-supplier"]) {
                NSInteger i = 0;
                for (ONOXMLElement *ccelement in celement.children) {
                    if ([ccelement.tag isEqualToString:@"dd"] && i == 0) {
                        medicine.brand = [ccelement stringValue];
                        i++;
                    }
                    else if ([ccelement.tag isEqualToString:@"dd"] && i == 1) {
                        medicine.manufacturer = [[ccelement stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
                    }
                    
                }
            }
            
            //商品條碼、名稱、規格型號、描述
            if ([celement.tag isEqualToString:@"dl"] && [celement.attributes[@"class"] isEqualToString:@"p-info"]) {
                NSInteger i = 0;
                for (ONOXMLElement *ccelement in celement.children) {
                    if ([ccelement.tag isEqualToString:@"dd"] && i == 0) {
                        medicine.code = [ccelement stringValue];
                        i++;
                    }
                    else if ([ccelement.tag isEqualToString:@"dd"] && i == 1) {
                        medicine.name = [ccelement stringValue];
                        i++;
                    }
                    else if ([ccelement.tag isEqualToString:@"dd"] && i == 2) {
                        medicine.specificagionmodel = [ccelement stringValue];
                        i++;
                    }
                    else if ([ccelement.tag isEqualToString:@"dd"] && i == 3) {
                        medicine.descriptions = [ccelement stringValue];
                    }
                }
            }
        }
        NSLog(@"%@",medicine);
    }];

首先把NSData轉成ONOXMLDocument,然后定位到你需要的信息位置(用xpath),定位到后得到相應的ONOXMLElement,其中的tag表示節點是什么,attributes是節點中的內容,其它屬性可以自己查看Ono

具體的解析我就不講了,這里我建了個HTMLMedicine的模型存儲,包含以下屬性:

@property (nonatomic, strong) NSString *code;                 //商品條碼
@property (nonatomic, strong) NSString *name;                 //名稱
@property (nonatomic, strong) NSString *specificagionmodel;   //規格型號
@property (nonatomic, strong) NSString *descriptions;         //描述
@property (nonatomic, strong) NSString *brand;                //商標
@property (nonatomic, strong) NSString *manufacturer;         //發布廠商

如果你的項目有集成AFNetworking這里也有個便捷的使用方式

最后是Ono手動集成配置的截圖,感謝閱讀:)


libxml2添加

Header Search Paths添加路徑
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容