2012-11-08 225 views
0

输入: -码生成不正确的HTML代码

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代码,但其产生其不是在期望的输出,I普林数组值似乎有正确的数据之前,其在这里,但使用.format东西越来越messedup ..任何人都可以指出什么是错的?

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

+0

HTML中有很多优秀的标记生成器和模板系统。生成适当的(符合标准的)(X)HTML比您想象的要多。请使用其中之一,而不是打印自己的。 – Keith

回答

0

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

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,我会说这是更易维护。

+0

正试图追加“hhttp:// CRLIST/CR /”到链接​​{CR}但它似乎并不需要它..我在这里失踪了什么? – user1795998

+0

@ user1795998:我不确定我了解你的问题。如果您使用的是Python内置的格式字符串,那么您需要在要填写的变量周围使用大括号。例如:'TEMPLATE =“”“{CR}”“”' – icktoofay