2017-07-16 11 views
13

buduję tabeli HTML z listy poprzez lxml.builder i dążąc do łącza w jednej z komórek tabelizmienna String jako href w lxml.builder

Lista generowana jest w sposób następujący:

with open('some_file.html', 'r') as f: 
    table = etree.parse(f) 
p_list = list() 
rows = table.iter('div') 
p_list.append([c.text for c in rows]) 
rows = table.xpath("body/table")[0].findall("tr") 
for row in rows[2:]: 
    p_list.append([c.text for c in row.getchildren()]) 

plik HTML, który I analizować to samo, który jest generowany przez lxml dalej, czyli skonfigurować jakiś rekursji dla celów testowych.

A oto jak zbudować tabelę

from lxml.builder import E 

page = (
E.html(
    E.head(
    E.title("title") 
    ), 
    E.body(
.... 

*[E.tr(
*[ 
     E.td(E.a(E.img(src=str(col)))) if ind == 8 else 
     E.td(E.a(str(col), href=str(col))) if ind == 9 else 
     E.td(str(col)) for ind, col in enumerate(row) 
    ] 
) for row in p_list ] 

Kiedy podać link, za pomocą literałów wszystko idzie dobrze.

E.td(E.a("link", href="url_address")) 

Jednak, gdy staram się lista wyjściowa wartość elementu (co jest https://blahblahblah.com) jako link

E.td(E.a(str(col), href=str(col))) 

komórka jest pusta, po prostu nic nie pokazał w komórce.

Gdybym określić tekst link jako dosłowne i umieścić str (col) do href, link jest pokazały normalnie, ale zamiast rzeczywistej href zawiera nazwę wygenerowanego pliku html.

Jeżeli wyjście po prostu, że wartość col jako ciąg

E.td(str(col)) 

ona pokazała normalnie, to znaczy nie jest pusty. Co jest nie tak z elementami i E.img?

Po prostu zauważyłem, że tak się dzieje tylko wtedy, gdy buduję listę z pliku html. Kiedy ręcznie buduję listę, tak jak to wszystko, wszystko jest w porządku.

p_list = [] 
p_element = ['id'] 
p_element.append('value') 
p_element.append('value2') 
p_list.append(p_element) 

Wyjście prądowe (zwrócić uwagę <a> i <href> znaczników)

<html> 
    <head> 
    <title>page</title> 
    </head> 
    <body> 
    <style type="text/css"> 
      th { 
       background-color: DeepSkyBlue; 
       text-align: center; 
       vertical-align: bottom; 
       height: 150px; 
       padding-bottom: 3px; 
       padding-left: 5px; 
       padding-right: 5px; 
     } 
     .vertical { 
       text-align: center; 
       vertical-align: middle; 
       width: 20px; 
       margin: 0px; 
       padding: 0px; 
       padding-left: 3px; 
       padding-right: 3px; 
       padding-top: 10px; 
       white-space: nowrap; 
       -webkit-transform: rotate(-90deg); 
       -moz-transform: rotate(-90deg);    
      }</style> 
    <h1>title</h1> 
    <p>This is another paragraph, with a</p> 
    <table border="2"> 
     <tr> 
     <th> 
      <div class="vertical">ID</div> 
     </th> 
     ... 
     <th> 
      <div class="vertical">I blacklisted him</div> 
     </th> 
     </tr> 
     <tr> 
     <td>1020</td> 
     <td>&#1058;&#1072;&#1080;&#1089;&#1080;&#1103;&#1057;&#1090;&#1088;&#1072;&#1093;&#1086;&#1083;&#1077;&#1090;</td> 
     <td>No</td> 
     <td>Female</td> 
     <td>None</td> 
     <td>&#1057;&#1072;&#1085;&#1082;&#1090;-&#1055;&#1077;&#1090;&#1077;&#1088;&#1073;&#1091;&#1088;&#1075;</td> 
     <td>&#1056;&#1086;&#1089;i&#1103;</td> 
     <td>None</td> 
     <td> 
      <a> 
      <img src="&#10;   "/> 
      </a> 
     </td> 
     <td> 
      <a href="&#10;   "> 
      </a> 
     </td> 
     ... 
     </tr> 
    </table> 
    </body> 
</html> 

Pożądany wyjście

<html> 
    <head> 
    <title>page</title> 
    </head> 
    <body> 
    <style type="text/css"> 
     th { 
       background-color: DeepSkyBlue; 
       text-align: center; 
       vertical-align: bottom; 
       height: 150px; 
       padding-bottom: 3px; 
       padding-left: 5px; 
       padding-right: 5px; 
     } 
     .vertical { 
       text-align: center; 
       vertical-align: middle; 
       width: 20px; 
       margin: 0px; 
       padding: 0px; 
       padding-left: 3px; 
       padding-right: 3px; 
       padding-top: 10px; 
       white-space: nowrap; 
       -webkit-transform: rotate(-90deg); 
       -moz-transform: rotate(-90deg);    
     }</style> 
    <h1>title</h1> 
    <p>This is another paragraph, with a</p> 
    <table border="2"> 
     <tr> 
     <th> 
      <div class="vertical">ID</div> 
     </th> 
     ... 
     <th> 
      <div class="vertical">I blacklisted him</div> 
     </th> 
     </tr> 
     <tr> 
     <td>1019</td> 
     <td>&#1052;&#1080;&#1093;&#1072;&#1080;&#1083;&#1055;&#1072;&#1074;&#1083;&#1086;&#1074;</td> 
     <td>No</td> 
     <td>Male</td> 
     <td>None</td> 
     <td>&#1057;&#1072;&#1085;&#1082;&#1090;-&#1055;&#1077;&#1090;&#1077;&#1088;&#1073;&#1091;&#1088;&#1075;</td> 
     <td>&#1056;&#1086;&#1089;i&#1103;</td> 
     <td>C.-&#1055;&#1077;&#1090;&#1077;&#1088;&#1073;&#1091;&#1088;&#1075;</td> 
     <td> 
      <a> 
      <img src="http://i.imgur.com/rejChZW.jpg"/> 
      </a> 
     </td> 
     <td> 
      <a href="http://i.imgur.com/rejChZW.jpg">link</a> 
     </td> 
     ... 
     </tr> 
    </table> 
    </body> 
</html> 
+0

@mzjn, tworząc listę dodany kod – Suncatcher

+0

To 'p_list'.Poprawiono vans – Suncatcher

+0

@ czysty HTML. Generowane dokładnie z tym samym builderem ElementTree. – Suncatcher

Odpowiedz

7

Mam to sam. Problem polegał nie na generowaniu, ale na analizie kodu HTML. Funkcja parsowania nie pobrała znaczników IMG i A zagnieżdżonych w TD, a te elementy listy były puste. Ze względu na rygorystyczną logikę programu (pobieranie z pliku + pobieranie z API strony) nie byłem w stanie wykryć przyczyny problemu.

Prawidłowe parsowania logika powinna być:

for row in rows[1:]: 
    data.append([ 
       c.find("a").text if c.find("a") is not None else 
       c.find("img").attrib['src'] if c.find("img") is not None else 
       c.text 
       for c in row.getchildren() 
       ]) 
0

tylko przypuszczenie, ale wygląda na to, 'str()' może uciekać. Wypróbuj E.td (E.a (col, href = col))

+0

Nie, też nie działa. – Suncatcher

+0

Czy wynik był taki sam? Wygląda na to, że "col" może być obiektem, a nie łańcuchem. Czy możesz wydrukować wartość z col poza linkiem? –

+0

Tak, jest ciągiem znaków: jeśli wydrukuję ('type (element)') na liście, wypisze ''. I tak, wynik jest taki sam. – Suncatcher