2016-07-06 11 views
2

Ich versuche, die Raw-HTML aus einer Reihe von lokalen HTML-Dateien zu greifen. Ich hatte etwas Hilfe von diesem Posten in die RAW-Datei immer in lesen:Wie rohe ich alle Roh-HTML in einem bestimmten XPath aus einer lokalen Datei in Python

Get all text inside a tag lxml

Aber der Code, den ich habe derzeit produziert die gesamte Datei anstelle einer Teilmenge. Gerade jetzt scheint mir eine Linie zu fehlen, in der ich einen xpath auswählen kann, den ich ergreifen möchte. Hier

ist der Code, den ich derzeit habe:

def stringify_children(node): 
    from lxml.etree import tostring 
    from itertools import chain 
    parts = ([node.text] + 
      list(chain(*([c.text, tostring(c), c.tail] for c 
      in node.getchildren()))) + 
      [node.tail]) 
    # filter removes possible Nones in texts and tails 
    return ''.join(filter(None, parts)) 

for filename in os.listdir('../news/article/'): 
    if (filename.endswith('.html') and not filename.startswith('._')): 
     print filename; 
     with open('../news/article/' + filename, "r") as f: 
      page=f.read(); 
     tree=html.fromstring(page); 
     maincontent = stringify_children(tree); 
     print maincontent; 

Mein Endziel ist in der Lage sein, das zu bekommen, in einem String und Ausgabe in einer lokalen Datei als nur, dass div.

Hier ist eine Beispieldatei:

<html> 

<head> 
    <title>Title</title> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> 
</head> 

<body> 
    <div class="container"> 
     <div class="row"> 
      <div class="col-xs-4"> 
       <div class="left-bar"></div> 
      </div> 
      <div class="col-xs-4"> 
       <div class="middle-bar"></div> 
      </div> 
      <div class="col-xs-4"> 
       <div class="right-bar"></div> 
      </div> 
     </div> 
     <div class="row"> 
      <div class="col-xs-3"> 
       <div class="navigation"></div> 
      </div> 
      <div class="col-xs-9"> 
       <div class="main-content"> 
        Hello 
        <br> 
        <br><a href="http://www.stackexchange.com">Click here to visit stack exchange</a> 
        <h1>This is an introduction</h1> 
        <h3>This is the third header</h3> 
        <p>Lorem ipsum dolor sit amet.....</p> 
        <p>Lorem ipsum dolor sit amet.....</p> 
        <p>Lorem ipsum dolor sit amet.....</p> 
        <ul> 
         <li>list text</li> 
         <li>list text</li> 
         <li>list text</li> 
         <li>list text</li> 
        </ul> 
        <div class="row"> 
         <div class="col-xs-4"><img src="#">More content 1</div> 
         <div class="col-xs-4"><img src="#">More content 2</div> 
         <div class="col-xs-4"><img src="#">More content 3</div> 
        </div> 

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

</body> 

</html> 

Ich möchte alle Inhalte unter der maincontent Klasse greifen. Hier ist die XPath dieser Klasse in dieser Datei:

XPath:/html/body/div/div [2]/div [2]/div

Das Programm sollte eine Ausgabe wie folgt vor:

    Hello 
        <br> 
        <br><a href="http://www.stackexchange.com">Click here to visit stack exchange</a> 
        <h1>This is an introduction</h1> 
        <h3>This is the third header</h3> 
        <p>Lorem ipsum dolor sit amet.....</p> 
        <p>Lorem ipsum dolor sit amet.....</p> 
        <p>Lorem ipsum dolor sit amet.....</p> 
        <ul> 
         <li>list text</li> 
         <li>list text</li> 
         <li>list text</li> 
         <li>list text</li> 
        </ul> 
        <div class="row"> 
         <div class="col-xs-4"><img src="#">More content 1</div> 
         <div class="col-xs-4"><img src="#">More content 2</div> 
         <div class="col-xs-4"><img src="#">More content 3</div> 
        </div> 
+0

Sie wollen also nicht das div selbst? Das gibt dir kaputtes HTML. Bist du sicher, dass du das willst? –

+0

Ja. Ich bin sicher, weil ich die Daten in ein neues HTML-Dokument importieren werde, das dieses Tag bereits erstellt hat. –

Antwort

0

Sie könnten BeautifulSoup versuchen. Ich bin nicht wirklich in sie versiert, aber man kann so etwas wie dieses (oder Reiniger tun, wenn Sie auf BeautifulSoup nachlesen :)

from bs4 import BeautifulSoup 
soup = BeautifulSoup(open("input.html"), 'html') 
x = soup.find_all(class_="main-content") 
for line in x[0].contents: 
    print line, 

Sie werden Ausgabe wie folgt erhalten:

 Hello 
     <br/> 
<br/> <a href="http://www.stackexchange.com">Click here to visit stack exchange</a> 
<h1>This is an introduction</h1> 
<h3>This is the third header</h3> 
<p>Lorem ipsum dolor sit amet.....</p> 
<p>Lorem ipsum dolor sit amet.....</p> 
<p>Lorem ipsum dolor sit amet.....</p> 
<ul> 
<li>list text</li> 
<li>list text</li> 
<li>list text</li> 
<li>list text</li> 
</ul> 
<div class="row"> 
<div class="col-xs-4"><img src="#"/>More content 1</div> 
<div class="col-xs-4"><img src="#"/>More content 2</div> 
<div class="col-xs-4"><img src="#"/>More content 3</div> 
</div> 

BeautifulSoup wird die HTML-Syntax "reparieren", wie die Änderung von
zu
und es wird den Abstand innerhalb der Elemente behalten. Lesen Sie die Dokumentation auf bei: https://www.crummy.com/software/BeautifulSoup/bs4/doc/

0

Mit lxml:

from lxml import html 

xm = html.fromstring(h) 
div = xm.xpath("//div[@class='main-content']")[0] 
print(div.text + "".join(map(html.tostring, div.xpath("./*")))) 

Oder:

from lxml import html 

xm = html.fromstring(h) 
eles = xm.xpath("//div[@class='main-content']/text() | //div[@class='main-content']/*") 
print("".join([ele if isinstance(ele, str) else html.tostring(ele) for ele in eles]))