整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          Ubuntu下libxml2的安裝和使用

          Ubuntu下libxml2的安裝和使用

          篇文章主要介紹libxml2的安裝和使用,xml文件的主要作用就是配置文件,實際的應(yīng)用在前面的章節(jié)Audio設(shè)備文件解析中有需要對audio_policy_configuration.xml文件解析,google使用的是開源庫libxml2,在源碼目錄/external/libxml2下面,現(xiàn)在就單獨對這個庫進行分析。

          在終端中執(zhí)行

          wang@wang:~/test$ sudo apt-get install libxml2-dev

          wang@wang:~/test$ sudo apt-get install libxml2

          可以通過

          wang@wang:~/test$ dpkg -s libxml2-dev

          查看安裝狀況。

          Package: libxml2-dev
          Status: install ok installed
          Priority: optional
          Section: libdevel
          Installed-Size: 2862
          Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
          Architecture: amd64
          Multi-Arch: same
          Source: libxml2
          Version: 2.9.1+dfsg1-3ubuntu4.12
          Depends: libxml2 (=2.9.1+dfsg1-3ubuntu4.12)
          Suggests: pkg-config
          Description: Development files for the GNOME XML library
           XML is a metalanguage to let you design your own markup language.
           A regular markup language defines a way to describe information in
           a certain class of documents (eg HTML). XML lets you define your
           own customized markup languages for many classes of document. It
           can do this because it's written in SGML, the international standard
           metalanguage for markup languages.
           .
           Install this package if you wish to develop your own programs using
           the GNOME XML library.
          Homepage: http://xmlsoft.org/

          通過執(zhí)行

          wang@wang:~/test$ dpkg -L libxml2-dev

          查看安裝位置

          /usr/include/libxml2
          /usr/include/libxml2/libxml
          /usr/include/libxml2/libxml/xpointer.h
          /usr/include/libxml2/libxml/catalog.h
          /usr/include/libxml2/libxml/xmlreader.h
          /usr/include/libxml2/libxml/xmlexports.h

          已經(jīng)安裝成功。

          • 接下來寫個demo使用libxml2進行文件解析,編寫CreateXmlFile.c
          #include<stdio.h>
          #include<libxml/parser.h>
          #include<libxml/tree.h>
           
          int main(int argc, char **argv)
          {
           	//Define document pointer
           	xmlDocPtr doc=xmlNewDoc(BAD_CAST"1.0");
           
          	//Define node pointer
          	xmlNodePtr root_node=xmlNewNode(NULL,BAD_CAST"root");
           
          	//Set the root element of the document
          	xmlDocSetRootElement(doc,root_node);
           
          	//Create child nodes directly in the root node
          	xmlNewTextChild(root_node,NULL,BAD_CAST"newnode1",BAD_CAST"newnode1 content");
          	xmlNewTextChild(root_node,NULL,BAD_CAST"newnode2",BAD_CAST"newnode2 content");
           
          	//Create a new node
          	xmlNodePtr node=xmlNewNode(NULL,BAD_CAST"node2");
          	//Create a new text node
          	xmlNodePtr content=xmlNewText(BAD_CAST"NODE CONTENT");
          	//Add a new node to parent
          	xmlAddChild(root_node,node);
          	xmlAddChild(node,content);
          	//Create a new property carried by a node
          	xmlNewProp(node,BAD_CAST"attribute",BAD_CAST"yes");
           
          	//Create a son and grandson node element
          	node=xmlNewNode(NULL,BAD_CAST"son");
          	xmlAddChild(root_node,node);
          	xmlNodePtr grandson=xmlNewNode(NULL,BAD_CAST"grandson");
          	xmlAddChild(node,grandson);
          	xmlAddChild(grandson,xmlNewText(BAD_CAST"THis is a grandson node"));
          						 
          	//Dump an XML document to a file
          	int nRel=xmlSaveFile("CreatedXmlDemo.xml",doc);
          	if(nRel !=-1) {
          		//Free up all the structures used by a document,tree included
          		xmlFreeDoc(doc);
          	}
          	return 0;
          }

          編譯

          wang@wang:~/test$ gcc -I/usr/include/libxml2 CreateXmlFile.c -o CreateXmlFile -lxml2

          可以看到執(zhí)行結(jié)果

          wang@wang:~/test$ gcc -I/usr/include/libxml2 CreateXmlFile.c -o CreateXmlFile -lxml2
          wang@wang:~/test$ ./CreateXmlFile
          wang@wang:~/test& ls
          CreatedXmlDemo.xml CreateXmlFile

          使用html打開生成的文件

          最后,如果你想學(xué)C/C++可以私信小編“01”獲取素材資料以及開發(fā)工具和聽課權(quán)限哦!

          XML是Python中一個強大的XML和HTML處理庫,它是基于libxml2和libxslt庫構(gòu)建的,并提供了一系列方便的API來處理XML和HTML文檔。在本教程中,我們將學(xué)習(xí)如何使用LXML庫來解析、操作和生成XML和HTML文檔。

          安裝LXML庫

          在使用LXML庫之前,我們需要先安裝它??梢允褂胮ip命令來安裝:

          pip install lxml
          

          解析XML和HTML文檔

          LXML庫提供了兩種解析器,即ElementTree和SAX解析器。ElementTree解析器將整個XML/HTML文檔解析成一個樹形結(jié)構(gòu),而SAX解析器則是基于事件的解析器,逐個處理文檔中的標(biāo)記。

          1、使用ElementTree解析器

          我們可以使用ElementTree解析器來解析XML/HTML文檔。首先,我們需要使用lxml.etree.parse()函數(shù)來讀取XML/HTML文檔并解析它。

          from lxml import etree
          
          # 讀取XML文件并解析
          tree=etree.parse("example.xml")
          
          # 獲取根元素
          root=tree.getroot()
          
          # 打印根元素的標(biāo)簽和屬性
          print("root tag:", root.tag)
          print("root attributes:", root.attrib)
          
          # 遍歷樹結(jié)構(gòu)并打印標(biāo)簽和文本內(nèi)容
          for element in root.iter():
              print("tag:", element.tag, "text:", element.text)
          

          2、使用SAX解析器

          我們可以使用lxml.sax模塊中的saxparser來處理XML/HTML文檔。首先,我們需要定義一個繼承自lxml.sax.ContentHandler類的處理器類,然后使用lxml.sax.parse()函數(shù)來解析XML/HTML文檔并將其傳遞給處理器類。

          from lxml import etree, sax
          
          # 定義處理器類
          class MyHandler(sax.ContentHandler):
              def __init__(self):
                  super().__init__()
          
              def startElement(self, name, attrs):
                  print("start element:", name)
                  for attr in attrs.items():
                      print("attribute:", attr)
          
              def endElement(self, name):
                  print("end element:", name)
          
              def characters(self, content):
                  print("characters:", content)
          
          # 解析XML文件
          parser=sax.make_parser()
          parser.setContentHandler(MyHandler())
          parser.parse("example.xml")
          

          操作XML和HTML文檔

          LXML庫提供了一系列方便的API來操作XML和HTML文檔。我們可以使用這些API來添加、刪除、修改和查詢文檔中的元素和屬性。

          1、添加元素和屬性

          我們可以使用Element對象的append()方法來添加子元素,使用Element對象的set()方法來添加屬性。

          from lxml import etree
          
          # 讀取XML文件并解析
          tree=etree.parse("example.xml")
          root=tree.getroot()
          
          # 添加子元素
          new_element=etree.Element("new_element")
          root.append(new_element)
          
          # 添加屬性
          new_element.set("attr1", "value1")
          new_element.set("attr2", "value2")
          
          # 保存修改后的文檔
          tree.write("example.xml", encoding="utf-8")

          2、刪除元素和屬性

          我們可以使用Element對象的remove()方法來刪除元素,使用Element對象的attrib.pop()方法來刪除屬性。

          from lxml import etree
          
          # 讀取XML文件并解析
          tree=etree.parse("example.xml")
          root=tree.getroot()
          
          # 查找要刪除的元素
          element_to_delete=root.find(".//element_to_delete")
          
          # 刪除元素
          root.remove(element_to_delete)
          
          # 刪除屬性
          root.attrib.pop("attr_to_delete")
          
          # 保存修改后的文檔
          tree.write("example.xml", encoding="utf-8")
          

          3、修改元素和屬性

          我們可以使用Element對象的find()方法和Element對象的text屬性來修改元素的文本內(nèi)容,使用Element對象的set()方法來修改屬性的值。

          from lxml import etree
          
          # 讀取XML文件并解析
          tree=etree.parse("example.xml")
          root=tree.getroot()
          
          # 查找要修改的元素
          element_to_modify=root.find(".//element_to_modify")
          
          # 修改元素文本內(nèi)容
          element_to_modify.text="new text content"
          
          # 修改屬性值
          element_to_modify.set("attr_to_modify", "new attribute value")
          
          # 保存修改后的文檔
          tree.write("example.xml", encoding="utf-8")
          

          4、查詢元素和屬性

          我們可以使用Element對象的find()方法和Element對象的attrib屬性來查詢元素和屬性。

          from lxml import etree
          
          # 讀取XML文件并解析
          tree=etree.parse("example.xml")
          root=tree.getroot()
          
          # 查詢元素
          element_to_find=root.find(".//element_to_find")
          
          # 查詢屬性
          attribute_to_find=root.attrib.get("attribute_to_find")
          
          # 打印查詢結(jié)果
          print("element_to_find:", element_to_find)
          print("attribute_to_find:", attribute_to_find)
          

          生成XML和HTML文檔

          LXML庫提供了ElementTree對象的tostring()方法來生成XML/HTML文檔。

          from lxml import etree
          
          # 創(chuàng)建XML文檔
          root=etree.Element("root")
          child1=etree.SubElement(root, "child1")
          child2=etree.SubElement(root, "child2")
          child1.text="text content"
          child2.set("attr1", "value1")
          child2.set("attr2", "value2")
          
          # 生成XML文檔
          xml_string=etree.tostring(root, pretty_print=True, encoding="utf-8")
          
          # 保存XML文檔
          with open("example.xml", "wb") as f:
              f.write(xml_string)
          

          總結(jié)

          本教程介紹了LXML庫的基本使用方法,包括解析XML/HTML文檔、操作XML/HTML文檔和生成XML/HTML文檔。LXML庫還提供了很多其他功能,例如XPath表達式的高級用法、CSS選擇器的支持、XML/HTML的序列化和反序列化等等。

          義上講,爬蟲只負責(zé)抓取,也就是下載網(wǎng)頁。而實際上,爬蟲還要負責(zé)從下載的網(wǎng)頁中提取我們想要的數(shù)據(jù),即對非結(jié)構(gòu)化的數(shù)據(jù)(網(wǎng)頁)進行解析提取出結(jié)構(gòu)化的數(shù)據(jù)(有用數(shù)據(jù))。

          所以說,網(wǎng)頁下載下來只是第一步,還有重要的一步就是數(shù)據(jù)提取。不同的爬蟲想要的數(shù)據(jù)不一樣,提取的數(shù)據(jù)也就不一樣,但提取方法都是類似的。

          最簡單的提取數(shù)據(jù)的方法,就是使用正則表達式,此種方法簡單,提取的邏輯也不能復(fù)雜,不然寫出的正則表達式就晦澀難懂,甚至不能提取復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。

          最終,老猿經(jīng)過多年的使用經(jīng)驗,選擇了lxml和xpath來解析網(wǎng)頁提取結(jié)構(gòu)化數(shù)據(jù)。順便說一下 BeautifulSoup,它也是一個很棒的解析HTML的工具,可以使用多個解析器,比如Python標(biāo)準(zhǔn)庫的parser,但是速度比較慢,也可以使用lxml作為解析器,但是它的使用方法、API跟lxml不太一樣。使用下來,還是lxml的API更舒服。

          lxml 對C語言庫 libxml2和 libxslt進行綁定,提供了Pythonic的API,它有一些主要特點:

          • 支持標(biāo)準(zhǔn)的XML
          • 支持(損壞)的HTML
          • 非常快的解析速度
          • Pythonic的API更易于使用
          • 使用Python的unicode字符串
          • 內(nèi)存安全(沒有段錯誤)
          • 不需要手動管理內(nèi)存

          總結(jié)為一句話就是,C語言的速度和Python的簡易相結(jié)合的神器。

          lxml有兩大部分,分別支持XML和HTML的解析:

          • lxml.etree 解析XML
          • lxml.html 解析html

          lxml.etree可以用來解析RSS feed,它就是一個XML格式的文檔。然而爬蟲抓取的絕大部分都是html網(wǎng)頁,所以,我們這里主要講述lxml.html解析網(wǎng)頁的方法。

          lxml.html 從html字符串生成文檔樹結(jié)構(gòu)

          我們下載得到的網(wǎng)頁就是一串html字符串,如何把它輸入給lxml.html模塊,從而生成html文檔的樹結(jié)構(gòu)呢?

          該模塊提供了幾種不同的方法:

          • parse(filename_url_or_file):
          • 輸入的是一個文件名、URL或文件對象(有read()方法)。
          • document_fromstring(string):
          • 輸入的是一個html的字符串,創(chuàng)建一個HTML文檔樹結(jié)構(gòu),它的根節(jié)點就是, 和 子節(jié)點。
          • fragment_fromstring(string, create_parent=False):
          • 返回輸入字符串的HTML片段。這個片段壁紙只含有一個element(元素),也就是單一節(jié)點,除非給出了create_parent 參數(shù),否則會報錯。
          • fragments_fromstring(string):
          • 返回包含輸入字符串中所有片段的列表。
          • fromstring(string):
          • 返回值依據(jù)輸入字符串而定,如果輸入看起來像是一個文檔,則返回document_fromstring(string),如果是一個單一片段,則返回fragment_fromstring(string)。

          下面我們通過具體示例來說明上面幾個方法的不同。

          document_fromstring 的使用方法

          In [1]: import lxml.html as lh
          In [2]: z=lh.document_fromstring('<span>abc</span><span>xyz</span>')
          # 可以看到,它自動加了根節(jié)點<html>
          In [3]: z
          Out[3]: <Element html at 0x7fc410667b88>
          In [4]: z.tag
          Out[4]: 'html'
          # 還加了<body>節(jié)點
          In [5]: z.getchildren()
          Out[5]: [<Element body at 0x7fc4101a3ae8>]
          # 把字符串的兩個節(jié)點放在了<body>里面
          In [6]: z.getchildren()[0].getchildren()
          Out[6]: [<Element span at 0x7fc410092bd8>, <Element span at 0x7fc410667c28>]
          

          fragment_fromstring 的使用

          In [11]: z=lh.fragment_fromstring(‘<div>abc</div><div>xyz</div>’)
          ---------------------------------------------------------------------------
          ParserError Traceback (most recent call last)
          <ipython-input-11-a11f9a0f71d1> in <module>()
          ----> 1 z=lh.fragment_fromstring(‘<div>abc</div><div>xyz</div>’)
          ~/.virtualenvs/py3.6/lib/python3.6/site-packages/lxml/html/__init__.py in fragment_fromstring(html, create_parent, base_url, parser, **kw)
           850 raise etree.ParserError(
           851 “Multiple elements found (%s)”
          --> 852 % ‘, ‘.join([_element_name(e) for e in elements]))
           853 el=elements[0]
           854 if el.tail and el.tail.strip():
          ParserError: Multiple elements found (div, div)
          # 可以看到,輸入是兩個節(jié)點(element)時就會報錯
          # 如果加上 create_parent 參數(shù),就沒問題了
          In [12]: z=lh.fragment_fromstring('<div>abc</div><div>xyz</div>', create_parent='p')
          In [13]: z.tag
          Out[13]: 'p'
          In [14]: z.getchildren()
          Out[14]: [<Element div at 0x7fc40a41a818>, <Element div at 0x7fc40a41aea8>]
          

          fragments_fromstring 的使用

          # 輸入字符串含有一個節(jié)點,則返回包含這一個節(jié)點的列表
          In [17]: lh.fragments_fromstring('<div>abc</div>')
          Out[17]: [<Element div at 0x7fc40a124ea8>]
          # 輸入字符串含有多個節(jié)點,則返回包含這多個節(jié)點的列表
          In [18]: lh.fragments_fromstring('<div>abc</div><div>xyz</div>')
          Out[18]: [<Element div at 0x7fc40a124b88>, <Element div at 0x7fc40a124f98>]
          

          fromstring 的使用

          In [27]: z=lh.fromstring('<div>abc</div><div>xyz</div>')
          In [28]: z
          Out[28]: <Element div at 0x7fc40a0eb368>
          In [29]: z.getchildren()
          Out[29]: [<Element div at 0x7fc410135548>, <Element div at 0x7fc40a0eb2c8>]
          In [30]: type(z)
          Out[30]: lxml.html.HtmlElement
          

          這里,fromstring輸入的如果是多個節(jié)點,它會給加一個父節(jié)點并返回。但是像html網(wǎng)頁都是從節(jié)點開始的,我們使用fromstring() 和 document_fromstring() 都可以得到完整的網(wǎng)頁結(jié)構(gòu)。

          從上面代碼中我們可以看到,那幾個函數(shù)返回的都是HtmlElement對象,也就是說,我們已經(jīng)學(xué)會了如何從html字符串得到HtmlElement的對象,下一節(jié)我們將學(xué)習(xí)如何操作HtmlElement對象,從中提取我們感興趣的數(shù)據(jù)。


          主站蜘蛛池模板: 国产午夜精品免费一区二区三区 | 亚洲一区二区三区首页| 亚洲AV综合色区无码一区 | 中文字幕精品一区二区三区视频| 成人日韩熟女高清视频一区| 亚洲av无一区二区三区| 无码少妇一区二区三区| 精品一区二区三区免费视频| 国语对白一区二区三区| 精品一区精品二区制服| 国产成人久久精品一区二区三区| 精品一区二区三区免费视频| 一区二区视频免费观看| 亚洲日韩国产一区二区三区| 日韩精品一区二区三区视频 | 久久99热狠狠色精品一区| 亚洲国产专区一区| 精品国产日韩亚洲一区在线| 濑亚美莉在线视频一区| 国产精品久久久久久一区二区三区| 台湾无码一区二区| 天堂资源中文最新版在线一区| 亚洲av乱码一区二区三区香蕉| 国产精品无码一区二区三区不卡 | 视频在线观看一区二区三区| 精品天海翼一区二区| 国产成人高清视频一区二区| 精品亚洲AV无码一区二区三区 | 亚洲一区二区三区免费| 日本一区午夜爱爱| 中文字幕不卡一区| 国产福利精品一区二区| 亚洲一区二区三区深夜天堂| 最新欧美精品一区二区三区| 无码AV一区二区三区无码 | 综合无码一区二区三区四区五区 | 国产免费一区二区视频| 在线免费一区二区| 午夜爽爽性刺激一区二区视频| 亚洲综合无码一区二区三区 | 精品一区精品二区制服|