Heim >Web-Frontend >HTML-Tutorial >So analysieren Sie HTML mit lxml

So analysieren Sie HTML mit lxml

高洛峰
高洛峰Original
2017-03-12 17:51:272003Durchsuche

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&#39;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>
&#39;&#39;&#39;
page = etree.HTML(html.lower().decode(&#39;utf-8&#39;))
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 553a280de7202c0dce8dfe871821475e< ;/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:

  90ce244b5a5321cadd932bf501f122e4Weltnachrichten nur auf dieser Seite94b3e26ee717c64999d7867364b1b4a3
  Ah, und hier ist übrigens noch etwas Text.
  e388a4556c0f65e1904146cc1a846bee.. und dies ist ein analysiertes Fragment ...94b3e26ee717c64999d7867364b1b4a3

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 „90ce244b5a5321cadd932bf501f122e4World News only on this page94b3e26ee717c64999d7867364b1b4a3“ 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: e388a4556c0f65e1904146cc1a846beehelloe388a4556c0f65e1904146cc1a846beeworld94b3e26ee717c64999d7867364b1b4a36fb279ad3fd4344cbdd93aac6ad173ac, 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”,它的意思是结束节点前面的内容,也就是说在“df250b2156c434f3390392d09b1c9563”与“94b3e26ee717c64999d7867364b1b4a3”之间的内容。它的源码里面的意思是“text after end tag”

  至于“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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn