如何从许多 html 文件中提取表格到一个 csv 文件?

1 人关注

我有很多html文件,我想提取每个html页面中的表格和表格外的其他信息,并将所有提取的信息合并到一个csv文件或tab delimited文件中。虽然有一个帖子的 "从多个html文件中提取文本到一个CSV文件的最佳方法" 我试着用我的html数据,速度很快,但结果是只有一列数据,当然它忽略了表外的信息。我把html文件预处理为 output.txt ,其中包括我需要的表内或表外的信息。,其中包括我用bash命令所需要的表内或表外的信息。

#!/bin/bash
for f in '*.html'; do   
    cat $f | sed -n '/tbody><tr/,/\/tbody>/p' > output.txt
done;

它做得很好,它给我们留下了一个非常干净的表格和其他我需要的信息。

output.txt的部分就像这样。

<tbody><tr><td><a href="fjzt-x.html?uid=NNNN">data11</a></td>
<td class="bzt">data12</td>
<td>data13</td>
    <td>data14</td>
<td>data15</td>
<td>data16</td>
<td>data17</td>
<td class="tdb"><span id="sNNNNN"></span></td>
<td class="tdb"><span id="zfNNNNN"></span></td>
<td class="bzt">--</td><td></td>
<script src="https://hq.sohujs.cn/list=data18" type="text/javascript" charset="gbk"></script>
<script type="text/javascript">getprice1('NNNNN',NNNN,NNN);</script>
</code></pre>
<td><a href="fjzt-x.html?uid=NNNN">data21</a></td>
<td class="bzt">data22</td>
<td>data23</td>
    <td>data24</td>
<td>data25</td>
<td>data26</td>
<td>data27</td>
<td class="tdb"><span id="sNNNNN"></span></td>
<td class="tdb"><span id="zfNNNNN"></span></td>
<td class="bzt">--</td><td></td>
<script src="https://hq.sohujs.cn/list=data28" type="text/javascript"  charset="gbk"></script>
<script type="text/javascript">getprice1('NNNNN',NNNN,NNN);</script>

我希望以制表符分隔的Out Sample是这样的。

data11  data12  data13  data14  data15  data16  data17  data18
data21  data22  data23  data24  data25  data26  data27  data28

谁能帮助我?Bash或python命令会更好。

linux
bash
html-table
export-to-csv
james
james
发布于 2018-12-04
2 个回答
0range
0range
发布于 2018-12-05
已采纳
0 人赞同

html可能是非常混乱的。因此我建议使用比bash脚本更高级的东西。既然你已经用python标签(在后来的编辑中正确地替换成了bash标签)标记了这个问题,我们就用 蟒蛇与BeautifulSoup .

EDIT: 在对这个答案的评论中,OP的作者澄清了OP真正想要的东西。

  • Collect the contents of td tags in a html table.
  • <td class="bzt">data12</td></code>
    
  • Additionally collect data from a link in the src attribute of one or more script tags in the same html file.
  • <script src="hq.sohujs.cn/list=data18" type="text/javascript" charset="gbk"></script>
    
  • 对当前工作目录中的所有html文件执行1.和2.。

  • 将其保存为csv表,字段用TAB("\t")分隔。

  • python3和BeautifulSoup的工作方案

    我扩展了这个答案的早期版本的脚本来做到这一点,并在评论中添加了一些解释。

    """module import"""
    from bs4 import BeautifulSoup
    import glob
    """obtain list of all html files in cwd"""
    filenames = glob.glob("*.html")
    for filename in filenames:
        """parse each file with bs4"""
        soup = BeautifulSoup(open(filename), 'html.parser')
        """obtain data from td tags"""
        tdTextList = [td.text.strip().replace("\n","") for td in soup.find_all("td")]
        """clean data: remove empty strings"""
        tdTextList = [td for td in tdTextList if not td=='']
        """obtain data from script tag attributes"""
        scriptTags = soup.findAll("script")
        for elementTag in scriptTags:
            src_attribute = elementTag.attrs.get("src")
            if src_attribute is not None:
                src_elements = src_attribute.split("=")
                if len(src_elements) > 1:
                    tdTextList.append(src_elements[1])
        """write data to output002.csv"""
        with open("output002.csv", "a") as outputfile:
            for tdText in tdTextList:
                outputfile.write(tdText)
                outputfile.write("\t")
            outputfile.write("\n")
    

    How to run

    在html文件所在的目录下的终端上,执行。

    python3 <script_name.py>
    

    另外,你也可以在脚本的开头将工作目录移到正确的位置(html文件所在的位置)。

    import os
    os.chdir("</path/to/directory>")
    

    python2和BeautifulSoup的工作方案

    由于OP的作者要求提供一个python2的版本,我在这里提供一个。与上面的python3版本的唯一区别是文件处理程序(python2使用file(),而不是open())。

    """module import"""
    from bs4 import BeautifulSoup
    import glob
    """obtain list of all html files in cwd"""
    filenames = glob.glob("*.html")
    for filename in filenames:
        """parse each file with bs4"""
        soup = BeautifulSoup(file(filename), 'html.parser')
        """obtain data from td tags"""
        tdTextList = [td.text.strip().replace("\n","") for td in soup.find_all("td")]
        """clean data: remove empty strings"""
        tdTextList = [td for td in tdTextList if not td=='']
        """obtain data from script tag attributes"""
        scriptTags = soup.findAll("script")
        for elementTag in scriptTags:
            src_attribute = elementTag.attrs.get("src")
            if src_attribute is not None:
                src_elements = src_attribute.split("=")
                if len(src_elements) > 1:
                    tdTextList.append(src_elements[1])
        """write data to output002.csv"""
        with file("output002.csv", "a") as outputfile:
            for tdText in tdTextList:
                outputfile.write(tdText)
                outputfile.write("\t")
            outputfile.write("\n")
    

    运行python2版本与上面的python3相类似。

    本答案的旧版本

    下面的脚本做了你描述的事情。

  • 收集当前目录中所有html文件的内容

  • 把它们写到带有标签分隔符的csv中。

  • 这里有一个脚本的例子。

    from bs4 import BeautifulSoup
    import glob
    filenames = glob.glob("*.html")
    tdTextList = []
    for filename in filenames:
        soup = BeautifulSoup(open(filename), 'html.parser')
        tdTextList += [td.text for td in soup.find_all("td")]
    with open("output001.csv", "w") as outputfile:
        for tdText in tdTextList:
            outputfile.write(tdText)
            outputfile.write("\t")
    

    这就是你描述的情况。这可能不是你想要的。

    请注意,这将产生一个有很长一行的文件(你没有指定何时需要新的一行)。如果任何一个td标签的内容包含一个换行符,它可能会意外地产生一个畸形的文件。

    为了使输出文件看起来更漂亮一些,让我们为每一个被读取的html文件写一个新行,并且让我们在将数据写入输出之前,将前导和尾部的空格以及换行符去除。

    from bs4 import BeautifulSoup
    import glob
    filenames = glob.glob("*.html")
    for filename in filenames:
        soup = BeautifulSoup(open(filename), 'html.parser')
        tdTextList = [td.text.strip().replace("\n","") for td in soup.find_all("td")]
        with open("output002.csv", "a") as outputfile:
            for tdText in tdTextList:
                outputfile.write(tdText)
                outputfile.write("\t")
            outputfile.write("\n")
    

    注意:你可以用bash shell运行这两个脚本。