首页 > 解决方案 > 如何跨行从html中获取文本

问题描述

我有一个 html 文件,如下所示。我想要Python做的是,当它看到关键字“存款到现金账户”时,它会抓取“class =”s14”的“存款到现金账户”和“class =”最接近它的$数字(12.32) s14""。与 (5.34) 中的“资产转入”相同。

<tr style="height:21pt">
<td style="width:366pt">
<p class="s14" style="padding-top: 7pt;padding-left: 19pt;text-indent: 0pt;text-align: left;">Deposits to Cash account</p>
</td>
<td style="width:150pt">
<p class="s14" style="padding-top: 7pt;padding-right: 2pt;text-indent: 0pt;text-align: right;">$12.32</p>
</td>
</tr>
<tr style="height:21pt">
<td style="width:366pt">
<p class="s14" style="padding-top: 2pt;padding-left: 19pt;text-indent: 0pt;text-align: left;">Asset transfers in</p>
</td>
<td style="width:150pt">
<p class="s14" style="padding-top: 2pt;padding-right: 2pt;text-indent: 0pt;text-align: right;">$5.34</p>
</td>
</tr>

我尝试使用 FOR 循环逐行遍历 html,我使用正则表达式来获取说“存款到现金帐户”的行,但不知道如何跨行抓取12.32

for line in htmlfile:

    if ('Deposits to Cash account' in line):
        lineClass = re.findall(r"<p (.*) style",line)   #grab "class="s14"
        print("inside for loop: ",lineClass)            
    if (lineClass[0] in line) and ('$' in line)
        number = re.findall(r"\$(.*)",line)

print("outside for loop: ",lineClass)

预期结果应该是字典:

["Deposits to Cash account": 12.32, 
"Asset transfers":5.34]

错误信息是NameError: name 'lineClass' is not defined

此外,“inside for loop:”Class=s14“”将被打印,“outside for loop:”将被打印丢失“Class=s14”。感觉就像 lineClass 变量在 for 循环完成后被清理了。这是为什么

标签: python

解决方案


如果您不能使用 3rd 方模块,例如beautifulsoup,您可以使用 Python 的内置( doc ) 制作“穷人” HTML 解析器:html.parser

data = '''<tr style="height:21pt">
<td style="width:366pt">
<p class="s14" style="padding-top: 7pt;padding-left: 19pt;text-indent: 0pt;text-align: left;">Deposits to Cash account</p>
</td>
<td style="width:150pt">
<p class="s14" style="padding-top: 7pt;padding-right: 2pt;text-indent: 0pt;text-align: right;">$12.32</p>
</td>
</tr>
<tr style="height:21pt">
<td style="width:366pt">
<p class="s14" style="padding-top: 2pt;padding-left: 19pt;text-indent: 0pt;text-align: left;">Asset transfers in</p>
</td>
<td style="width:150pt">
<p class="s14" style="padding-top: 2pt;padding-right: 2pt;text-indent: 0pt;text-align: right;">$5.34</p>
</td>
</tr>'''

from html.parser import HTMLParser

class MyHTMLParser(HTMLParser):
    grab_data_fn = lambda data: None
    parsed_data = []

    def handle_starttag(self, tag, attrs):
        attrs = dict(attrs)
        if tag=='p' and 'class' in attrs and 's14' in attrs['class']:
            MyHTMLParser.grab_data_fn = lambda data: MyHTMLParser.parsed_data.append(data.strip())

    def handle_endtag(self, tag):
        MyHTMLParser.grab_data_fn = lambda data: None

    def handle_data(self, data):
        MyHTMLParser.grab_data_fn(data)


parser = MyHTMLParser()
parser.feed(data)
parsed_data = parser.parsed_data

deposits = parsed_data[parsed_data.index('Deposits to Cash account') + 1]
transfers = parsed_data[parsed_data.index('Asset transfers in') + 1]

print('Deposits =',deposits)
print('Transfers =',transfers)

打印:

Deposits = $12.32
Transfers = $5.34

但是,最好使用成熟的库,如beautifulsoup、或。有了它们,您可以使用丰富的 API(如 XPath、CSS 选择器等)轻松获取数据。seleniumscrapylxml


推荐阅读