【问题标题】:String variable as href in lxml.builder字符串变量作为 lxml.builder 中的 href
【发布时间】:2017-12-21 06:26:27
【问题描述】:

我正在通过 lxml.builder 从列表中构建 HTML 表格,并努力在其中一个表格单元格中建立链接

列表的生成方式如下:

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()])

我解析的 HTML 文件与 lxml 进一步生成的 相同,即我为测试目的设置了某种递归。

这是我构建表格的方式

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 ]

当我通过文字指定链接时,一切都很好。

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

但是,当我尝试将列表元素值(https://blahblahblah.com)作为链接输出时

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

单元格为空,单元格中没有显示任何内容。

如果我将链接文本指定为文字并将str (col) 放入href,则链接正常显示,但它包含生成的html 文件的名称,而不是真正的href。

如果我将 col 值作为字符串输出

E.td(str(col))

正常显示,即不为空E.aE.img 元素有什么问题?

刚刚注意到只有当我从 html 文件构建列表时才会发生这种情况。当我像这样手动构建列表时,一切正常。

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

电流输出(注意<a><href>标签)

   <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>

期望的输出

<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>

【问题讨论】:

  • @mzjn,添加列表形成代码
  • 它是p_list。更正了变量
  • @纯 HTML。完全使用相同的 ElementTree 生成器生成。
  • 我为测试目的设置了递归:我生成 HTML,然后再次解析它。
  • 添加了 HTML 示例。我暴露了我所有的代码。不能再添加了

标签: python html python-3.x lxml literals


【解决方案1】:

我自己搞定了。问题不在于生成,而在于解析 HTML。解析函数没有获取嵌套在TD 中的IMGA 标签,并且列表的这些元素是空的。由于程序的严格逻辑(从文件获取 + 从站点 API 获取),我无法检测到问题的原因。

正确的解析逻辑应该是:

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()
                ])

【讨论】:

    【解决方案2】:

    只是一个猜测,但看起来 'str()' 可能会逃脱它。试试 E.td(E.a(col, href=col))

    【讨论】:

    • 结果一样吗?看起来“col”可能是一个对象而不是字符串。你能从链接外的 col 打印值吗?
    • 是的,它是字符串:如果我在整个列表中打印(type(element)),它会打印&lt;class 'str'&gt;。是的,结果是一样的。
    • 这似乎更像是一个解析问题,而不是输出问题。当我在解析后打印列表时,它会打印出所有元素都很好除了第8个和第9个元素:它们是空的。
    猜你喜欢
    • 2015-12-25
    • 2021-10-31
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多