In diesem Artikel wird die Methode zum Parsen von HTML mit lxml vorgestellt.
Demonstrieren Sie zunächst ein Codebeispiel zum Abrufen eines Seitenlinks:
#coding=utf-8 from lxml import etree html = ''' <html> <head> <meta name="content-type" content="text/html; charset=utf-8" /> <title>友情链接查询 - 站长工具</title> <!-- uRj0Ak8VLEPhjWhg3m9z4EjXJwc --> <meta name="Keywords" content="友情链接查询" /> <meta name="Description" content="友情链接查询" /> </head> <body> <h1 class="heading">Top News</h1> <p style="font-size: 200%">World News only on this page</p> Ah, and here's some more text, by the way. <p>... and this is a parsed fragment ...</p> <a href="http://www.cydf.org.cn/" rel="nofollow" target="_blank">青少年发展基金会</a> <a href="http://www.4399.com/flash/32979.htm" target="_blank">洛克王国</a> <a href="http://www.4399.com/flash/35538.htm" target="_blank">奥拉星</a> <a href="http://game.3533.com/game/" target="_blank">手机游戏</a> <a href="http://game.3533.com/tupian/" target="_blank">手机壁纸</a> <a href="http://www.4399.com/" target="_blank">4399小游戏</a> <a href="http://www.91wan.com/" target="_blank">91wan游戏</a> </body> </html> ''' page = etree.HTML(html.lower().decode('utf-8')) hrefs = page.xpath(u"//a") for href in hrefs: print href.attrib
Das gedruckte Ergebnis ist:
{'href': 'http://www.cydf.org.cn/', 'target': '_blank', 'rel': 'nofollow'}
{'href': 'http://www.4399.com/flash/32979.htm', 'target': '_blank'}
{'href': 'http://www.4399 .com /flash/35538.htm', 'target': '_blank'}
{'href': 'http://game.3533.com/game/', 'target': '_blank'}
{'href': 'http://game.3533.com/tupian/', 'target': '_blank'}
{'href': 'http://www.4399.com/' , ' target': '_blank'}
{'href': 'http://www.91wan.com/', 'target': '_blank'}
Wenn Sie < a>< ;/a>Der Inhalt zwischen
for href in hrefs:
print href.text
Das Ergebnis ist:
Youth Development Foundation
Rock Kingdom
Aola Star
Handyspiel
Handyhintergrund
4399 Minispiel
91wan-Spiel
Dinge, die Sie vor der Verwendung von lxml beachten sollten: Stellen Sie zunächst sicher, dass der HTML-Code mit utf-8 dekodiert wurde, d. h. code = html.decode('utf-8', 'ignore'), andernfalls treten Analysefehler auf. Da Chinesisch in utf-8 codiert ist und dann eine Form wie „/u2541“ annimmt, geht lxml davon aus, dass das Tag endet, wenn es auf „/“ trifft.
XPATH verwendet grundsätzlich eine verzeichnisbaumartige Methode, um den Pfad im XML-Dokument zu beschreiben. Verwenden Sie beispielsweise „/“ als Trennung zwischen oberer und unterer Ebene. Das erste „/“ stellt den Wurzelknoten des Dokuments dar (beachten Sie, dass es sich nicht auf den äußersten Tag-Knoten des Dokuments bezieht, sondern auf das Dokument selbst). Bei einer HTML-Datei sollte der äußerste Knoten beispielsweise „/html“ sein.
Um ein bestimmtes HTML-Tag zu finden, können Sie einen absoluten Pfad ähnlich dem Dateipfad verwenden, z. B. page.xpath(u"/html/body/p") Finden Sie den Körperknoten. Suchen Sie alle p-Tags. Sie können auch einen relativen Pfad verwenden, der dem Dateipfad ähnelt. Sie können ihn wie folgt verwenden: page.xpath(u"//p"). Dadurch werden alle p-Tags im Ganzen gefunden HTML-Code:
Weltnachrichten nur auf dieser Seite
.. und dies ist ein analysiertes Fragment ...
Hinweis: XPATH gibt nicht unbedingt den einzigen Knoten zurück, sondern alle Knoten, die die Bedingungen erfüllen. Wie oben gezeigt, wird es herausgenommen, solange es sich um das p-Tag im Körper handelt, unabhängig davon, ob es sich um den Knoten der ersten, zweiten oder dritten Ebene des Körpers handelt.
Wenn Sie den Umfang weiter eingrenzen und „
World News only on this page
“ direkt finden möchten, was sollten Sie tun? Dies erfordert das Hinzufügen von Filterbedingungen. Die Filtermethode besteht darin, „[““]“ zum Hinzufügen von Filterbedingungen zu verwenden. Es gibt eine Filtersyntax in lxml:p = page.xpath(u"/html/body/p[@style='font-size: 200%']")
Oder : p = page.xpath(u"//p[@style='font-size:200%']")
Auf diese Weise wird der p-Knoten mit dem Stil „font-size:200%“ im Körper wird herausgenommen. Hinweis: Diese p-Variable ist eine Liste von lxml.etree._Element-Objekten. Das Ergebnis von p[0].text ist nur Weltnachrichten auf dieser Seite. das heißt, der Wert zwischen den Tags; p Das Ergebnis von [0].values() ist Schriftgröße: 200 %, also alle -Attribut--Werte. Unter diesen stellt @style den Attributstil dar. Ebenso können Sie auch @name, @id, @value, @href, @src, @class....
verwenden So etwas gibt es im Tag nicht. Was tun mit Attributen? Dann können Sie text(), position() und andere -Funktionen zum Filtern verwenden. Die Funktion text() bedeutet, den im Knoten enthaltenen Text abzurufen. Beispiel:
hello
world
< /p>, verwenden Sie „p[text()='hello']“, um das p zu erhalten, und world ist der text() von p . Die Funktion position() bedeutet, die Position des Knotens zu ermitteln. „li[position()=2]“ bedeutet beispielsweise, den zweiten li-Knoten zu erhalten, der auch als „li[2]“ weggelassen werden kann.Sie sollten jedoch auf die Reihenfolge der numerischen Positionierung und Filterbedingungen achten. „ul/li[5][@name='hello']“ bedeutet beispielsweise, dass das fünfte Element li unter ul genommen wird und sein Name hello sein muss, sonst wird es leer zurückgegeben. Wenn Sie „ul/li[@name=‘hello‘][5]“ verwenden, ist die Bedeutung anders. Es bedeutet, den fünften Li-Knoten mit dem Namen „hello“ unter ul zu finden.
此外,“*”可以代替所有的节点名,比如用"/html/body/*/span"可以取出body下第二级的所有span,而不管它上一级是p还是p或是其它什么东东。
而 “descendant::”前缀可以指代任意多层的中间节点,它也可以被省略成一个“/”。比如在整个HTML文档中查找id为“leftmenu”的 p,可以用“/descendant::p[@id='leftmenu']”,也可以简单地使用“ //p[@id='leftmenu']”。
text = page.xpath(u"/descendant::*[text()]")表示任意多层的中间节点下任意标签之间的内容,也即实现蜘蛛抓取页面内容功能。以下内容使用text属性是取不到的:
<p class="news"> 1. <b>无流量站点清理公告</b> 2013-02-22<br /> 取不到的内容 </p> <p class="news"> 2. <strong>无流量站点清理公告</strong> 2013-02-22<br /> 取不到的内容 </p> <p class="news"> 3. <span>无流量站点清理公告</span> 2013-02-22<br /> 取不到的内容 </p> <p class="news"> 4. <u>无流量站点清理公告</u> 2013-02-22<br /> 取不到的内容 </p>
这些“取不到的内容”使用这个是取不到的。怎么办呢?别担心,lxml还有一个属性叫做“tail”,它的意思是结束节点前面的内容,也就是说在“
”与“
至于“following-sibling::”前缀就如其名所说,表示同一层的下一个节点。"following-sibling::*"就是任意下一个节点,而“following-sibling::ul”就是下一个ul节点。
如果script与style标签之间的内容影响解析页面,或者页面很不规则,可以使用lxml.html.clean模块。模块 lxml.html.clean 提供 一个Cleaner 类来清理 HTML 页。它支持删除嵌入或脚本内容、 特殊标记、 CSS 样式注释或者更多。
cleaner = Cleaner(style=True, scripts=True,page_structure=False, safe_attrs_only=False)
print cleaner.clean_html(html)
注意,page_structure,safe_attrs_only为False时保证页面的完整性,否则,这个Cleaner会把你的html结构与标签里的属性都给清理了。使用Cleaner类要十分小心,小心擦枪走火。
忽略大小写可以:
page = etree.HTML(html)
keyword_tag = page.xpath("//meta[translate(@name,'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 'abcdefghjiklmnopqrstuvwxyz')='keywords']")
Das obige ist der detaillierte Inhalt vonSo analysieren Sie HTML mit lxml. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!