0

输入:-

   CRlist
  [['CR', 'FA', 'CL', 'TITLE'], ['409452', 'WLAN', '656885', 'Age out RSSI values from buffer in Beacon miss scenario'], ['379104', 'BT', '656928', 'CR379104: BT doesn\xe2\x80\x99t work that Riva neither sends HCI Evt for HID ACL data nor response to HCI_INQUIRY after entering into pseudo sniff subrating mode.']]

我有以下 pythong 代码来生成 HTML 代码,但它生成了一个不期望的输出,我将数组值 pring 之前似乎有正确的数据,但是在 using.format 时,有些东西变得混乱了..谁能指出什么是错的这里?

for i in range(len(CRlist)):
    if i==0:
        continue
    for j in range(len(CRlist[0])):
        print "i"
        print i
        print "j"
        print j
        print "CRlist[i][j]"
        print CRlist[i][j]//right data here
        CRstring += """
        <tr>
        <td><a href="{CR}">{CR}</a></td>
        <td>{FA}</td>
        <td>{CL}</td>
        <td>{Title}</td>
        </tr>""".format(
            CR=CRlist[i][j],
            FA=CRlist[i][j],
            CL=CRlist[i][j],
            Title=CRlist[i][j],
            )
CRstring += "\n</table>\n"

我对输出的期望,但创建不正确

   <tr>
   <td><a href="409452">409452</a></td>
   <td>WLAN</td>
   <td>656885</td>
   <td>Age out RSSI values from buffer in Beacon miss scenario</td>
   </tr>
    ..............

实际输出,行单元格数据是多余的

                   <tr>
                   <td><a href="409452">409452</a></td>
                   <td>409452</td>
                   <td>409452</td>
                   <td>409452</td>
                   </tr>
                   <tr>
                   <td><a href="WLAN">WLAN</a></td>
                   <td>WLAN</td>
                   <td>WLAN</td>
                   <td>WLAN</td>
                   </tr>
                   <tr>
                   <td><a href="656885">656885</a></td>
                   <td>656885</td>
                   <td>656885</td>
                   <td>656885</td>
                   </tr>
                   <tr>
                   <td><a href="Age out RSSI values from buffer in Beacon miss scenario">Age out RSSI values from buffer in Beacon miss scenario</a></td>
                   <td>Age out RSSI values from buffer in Beacon miss scenario</td>
                   <td>Age out RSSI values from buffer in Beacon miss scenario</td>
                   <td>Age out RSSI values from buffer in Beacon miss scenario</td>
                   </tr>
                   <tr>
                   <td><a href="379104">379104</a></td>
                   <td>379104</td>
                   <td>379104</td>
                   <td>379104</td>
                   </tr>
                   <tr>
                   <td><a href="BT">BT</a></td>
                   <td>BT</td>
                   <td>BT</td>
                   <td>BT</td>
                   </tr>
                   <tr>
                   <td><a href="656928">656928</a></td>
                   <td>656928</td>
                   <td>656928</td>
                   <td>656928</td>
                   </tr>
                   <tr>
                   <td><a href="CR379104: BT doesnΓÇÖt work that Riva neither sends HCI Evt for HID ACL data nor response to HCI_INQUIRY after entering into pseudo sniff subrating mode.">CR379104: BT doesnΓÇÖt work that Riva neither sends HCI Evt for HID ACL data nor response to HCI_INQUIRY after entering into pseudo sniff subrating mode.</a></td>
                   <td>CR379104: BT doesnΓÇÖt work that Riva neither sends HCI Evt for HID ACL data nor response to HCI_INQUIRY after entering into pseudo sniff subrating mode.</td>
                   <td>CR379104: BT doesnΓÇÖt work that Riva neither sends HCI Evt for HID ACL data nor response to HCI_INQUIRY after entering into pseudo sniff subrating mode.</td>
                   <td>CR379104: BT doesnΓÇÖt work that Riva neither sends HCI Evt for HID ACL data nor response to HCI_INQUIRY after entering into pseudo sniff subrating mode.</td>
                   </tr>
/table>

=========PLlist==========

4

1 回答 1

0

此代码为每个模板变量提供相同的值:

CR=CRlist[i][j],
FA=CRlist[i][j],
CL=CRlist[i][j],
Title=CRlist[i][j],

显然,这并不像您预期​​的那样工作。这是另一种写法:

TEMPLATE = """
    <tr>
    <td><a href="{CR}">{CR}</a></td>
    <td>{FA}</td>
    <td>{CL}</td>
    <td>{Title}</td>
    </tr>
"""

for i, item in enumerate(CRlist):
    if i == 0:
        continue

    CRstring += TEMPLATE.format(
        CR=item[0],
        FA=item[1],
        CL=item[2],
        Title=item[3],
    )

CRstring += "\n</table>\n"

您甚至可以通过对列表进行切片来删除ienumerate位:

for item in CRList[1:]:
    CRstring += # ...

由于您正在生成 HTML 并使用用户输入(至少我假设)并且没有转义 HTML,因此您遇到了 XSS 漏洞。让我们也解决这个问题:

# near the top of the file:
import cgi

# later...
# ...
CRstring += TEMPLATE.format(
    CR=cgi.escape(item[0]),
    FA=cgi.escape(item[1]),
    # ...
)

进一步改进

这一切都很好,但正如评论中有人指出的那样,使用真正的模板引擎可能会更好。我个人喜欢Jinja2。下面是你如何做到这一点:

    {%- for item in cr_list[1:] %}
        <tr>
            <td><a href="{{ item[0] | escape }}">{{ item[0] | escape }}</a></td>
            <td>{{ item[1] | escape }}</td>
            <td>{{ item[2] | escape }}</td>
            <td>{{ item[3] | escape }}</td>
        </tr>
    {%- endfor %}
</table>

此外,您可能希望将数据放入对象中。例如:

class CREntry(object):
    def __init__(self, cr, fa, cl, title):
        self.cr = cr
        self.fa = fa
        self.cl = cl
        self.title = title

然后你可以很简单地转换它:

entries = [CREntry(*entry) for entry in CRlist[1:]]

然后您的代码变得更加清晰,能够引用entry.title而不是item[3].

您可能还想使用PEP 8中概述的普通 Python 约定。

如果你已经完成了,你的代码如下所示:

import jinja2

env = jinja2.Environment(autoescape=True)  # no more | escape everywhere!

template = env.from_string(r"""
        {%- for entry in entries %}
            <tr>
                <td><a href="{{ entry.cr }}">{{ entry.cr }}</a></td>
                <td>{{ entry.fa }}</td>
                <td>{{ entry.cl }}</td>
                <td>{{ entry.title }}</td>
            </tr>
        {%- endfor %}
    </table>
""")

class CREntry(object):
    # ...

# later...
entries = [CREntry(*entry) for entry in cr_list]
cr_string = template.render(entries=entries)

其他地方的代码多一点,但当您实际生成 HTML 时会少一些,我会说它易于维护。

于 2012-11-08T03:55:05.713 回答