【问题标题】:Extracting string from html text从html文本中提取字符串
【发布时间】:2020-02-28 05:27:03
【问题描述】:

我正在获取带有 curl 的 html,并且只需要提取 第二个表格语句。 请注意,卷曲的 html 是单个字符串且未格式化。 为了更好地解释,请参见以下内容:(...代表更多 html)

...
<table width="100%" cellpadding="0" cellspacing="0" class="table">
...
</table>
...
#I need to extract the following table
#from here
<table width="100%" cellpadding="4">
...
</table> #to this
...

到目前为止,我尝试了多条 SED 行,而且我认为尝试像这样匹配第二个表并不是顺利的方式:

sed -n '/<table width="100%" cellpadding="4"/,/table>/p'

【问题讨论】:

  • 你结婚了吗?改用 HTML/XML 解析器会更健壮。
  • 不管做什么工作都会很棒
  • 您要打印整个 语句还是只打印
    语句中的内容?
  • @curusarn 完整声明
  • 我已经编写了一个打印表格语句的脚本。 (见下面我的回答)如果它​​不适合你,请务必发表评论。

标签: html regex sed html-parsing extraction


【解决方案1】:

将下面的脚本保存为script.py 并像这样运行它:

python3 script.py input.html

此脚本解析 HTML 并检查属性(widthcellpadding)。这种方法的优点是,如果您更改 HTML 文件的格式,它仍然可以工作,因为脚本会解析 HTML,而不是依赖精确的字符串匹配。

from html.parser import HTMLParser
import sys

def print_tag(tag, attrs, end=False):
    line = "<" 
    if end:
        line += "/"
    line += tag
    for attr, value in attrs:
        line += " " + attr + '="' + value + '"'
    print(line + ">", end="")

if len(sys.argv) < 2:
    print("ERROR: expected argument - filename")
    sys.exit(1)

with open(sys.argv[1], 'r', encoding='cp1252') as content_file:
    content = content_file.read()

do_print = False

class MyHTMLParser(HTMLParser):
    def handle_starttag(self, tag, attrs):
        global do_print
        if tag == "table":
            if ("width", "100%") in attrs and ("cellpadding", "4") in attrs:
                do_print = True
        if do_print:
            print_tag(tag, attrs)

    def handle_endtag(self, tag):
        global do_print
        if do_print:
            print_tag(tag, attrs=(), end=True)
            if tag == "table":
                do_print = False

    def handle_data(self, data):
        global do_print
        if do_print:
            print(data, end="")

parser = MyHTMLParser()
parser.feed(content)

【讨论】:

  • 感谢您的宝贵时间。我收到以下错误: Traceback(最近一次调用最后一次):文件“script.py”,第 11 行,在 content = content_file.read() 文件“/usr/lib/python3.7/codecs.py” ,第 322 行,在 decode (result, used) = self._buffer_decode(data, self.errors, final) UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf6 in position 230: invalid start byte
  • 立即尝试。你知道你的文件是什么编码的吗?
  • 非常感谢,工作就像一个魅力!我现在得到了所有的内容。唯一缺少的是,table 标记之间的每个 html 标记,例如: 、 和 都丢失了。就像我说的内容在那里,但格式标签丢失了
  • @loyd 哦,我犯了一个愚蠢的错误。立即尝试。
  • 非常感谢您的帮助和工作!你帮我解决了这个问题!感谢您的宝贵时间 :) 祝您玩得愉快!
【解决方案2】:

html 解析器会更好,但您可以像这样使用awk

awk '/<table width="100%" cellpadding="4">/ {f=1} f; /<\/table>/ {f=0}' file
<table width="100%" cellpadding="4">
...
</table> #to this
  • /&lt;table width="100%" cellpadding="4"&gt;/ {f=1} 找到启动时将标志 f 设置为 true
  • f; 如果标志 f 为真,则执行默认操作,打印行。
  • /&lt;\/table&gt;/ {f=0} 找到结束时,清除标志f 以停止打印。

这个也可以用,不过喜欢flag control更好:

awk '/<table width="100%" cellpadding="4">/,/<\/table>/' file
<table width="100%" cellpadding="4">
...
</table> #to this

【讨论】:

  • 感谢您的回答。由于某种原因,它仍然打印在 cellpadding="0" :/ 的第一个表
  • @loyd 我刚刚从您的帖子中剪切和过去的数据,并且在 ubuntu 18.04 上运行良好。应该适用于大多数系统。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-08
  • 1970-01-01
  • 1970-01-01
  • 2014-05-20
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
相关资源
最近更新 更多