python - 解析 HTML Python、BeautifulSoup

标签 python html csv beautifulsoup

我有几个 html 文档,其中包含以下类型的信息:

<td class="principal-col">
<div class="pr-person">
<div class="name"><span id="pr_person-icon" class="bullet-male-left"></span><span class="person-link">Thomas A /Dumpling/</span></div>
<table class="events" border="0">
<tr>
<td class="factLabel">event1:&nbsp;</td>
<td>
4 February 1940          
<br/>
</td>
</tr> 
<tr>
<td class="factLabel">event2:&nbsp;</td>
<td>
9 October 2002   
<br/>Laplata, Md
</td>
</tr>

我正在尝试提取人名(此处:Thomas A Dumpling),以及 event1(此处:1940 年 2 月 4 日)和 event2 日期和地点(此处:2002 年 10 月 9 日,马里兰州拉普拉塔),从 html 文件中获取内容,并将内容放入 csv 文件“data.csv”的名为“Name”、“Event1”、“Event2”的列中。

如何从上面的 html 代码中提取名称,到目前为止我还没有弄清楚。对于 event1 和 event2 日期信息,以下代码对于类似的 html 文件效果很好,但对于我上面发布的 html 代码类型根本不起作用;也就是说,执行了以下 Python 代码,但它在 csv 文件的相应列中添加了“missing”。

from bs4 import BeautifulSoup
import csv
import re
import glob
import os

f= csv.writer(open('data.csv', 'w'))
f.writerow(["Event1", "Event2"]) 

path = 'C:\\File-Path\\*'

for infile in glob.glob(os.path.join(path, "148929_S1N8-DQ7.htm")):
    soup = BeautifulSoup (open(infile))
    myDict = {}
    for item in ["event1:", "event2:"]:
        try:
            myDict[item] = soup.find('td', text=re.compile(r'^%s$' % item)).findNext('td').text
            myDict[item] = myDict[item].strip()
            myDict[item] = myDict[item].lstrip()
            myDict[item] = myDict[item].rstrip()
            myDict[item] = myDict[item].encode('UTF-8')
        except Exception:
            myDict[item] = "missing"
            pass
    f.writerow([myDict["event1:"], myDict["event2:"]])

非常感谢任何指点!

最佳答案

首先,我将您的示例数据转换为有效的 html 页面并对其进行了 pretty-print 。这使得更容易看到发生了什么:

<html><body><table><tr>
<td class="principal-col">
  <div class="pr-person">
    <div class="name">
      <span id="pr_person-icon" class="bullet-male-left"></span>
      <span class="person-link">Thomas A /Dumpling/</span>
    </div>
    <table class="events" border="0">
      <tr>
        <td class="factLabel">event1:&nbsp;</td>
        <td>4 February 1940<br/></td>
      </tr> 
      <tr>
        <td class="factLabel">event2:&nbsp;</td>
        <td>9 October 2002<br/>Laplata, Md</td>
      </tr>
    </table>
  </div>
</td>
</tr></table></body></html>

然后稍微改变一下你的程序:

from bs4 import BeautifulSoup
import csv
import glob
import os

DATA_PATH = "c:\\file_path\\"
FILESPEC  = "*.htm"
OUTFILE   = "data.csv"

def main():
    data = []
    for fname in glob.glob(os.path.join(DATA_PATH, FILESPEC)):
        with open(fname) as inf:
            pg = BeautifulSoup(inf.read())
            for person in pg.findAll('td', {'class':'principal-col'}):
                data.append(get_data(person))
    data.sort()

    with open(os.path.join(DATA_PATH, OUTFILE), 'wb') as outf:
        outcsv = csv.writer(outf)
        outcsv.writerow(["Name", "Born", "Hired"])
        outcsv.writerows(data)

if __name__ == "__main__":
    main()

只留下实际的解析代码,

def get_string(node, default=''):
    if node:
        return ', '.join(node.stripped_strings)
    else:
        return default

def get_data(td_princ):
    name = get_string(td_princ.find('span', {'class':'person-link'})).replace('/', '')

    birth = hired = '(missing)'
    for event in td_princ.find('table', {'class': 'events'}).findAll('tr'):
        cnt = [get_string(cell) for cell in event.findAll('td')]
        if len(cnt) == 2:
            if cnt[0] == "event1:":
                birth = cnt[1]
            elif cnt[0] == "event2:":
                hired = cnt[1]
    return (name, birth, hired)

当针对示例数据运行时,会生成一个如下所示的 csv 文件

Name,Born,Hired
Thomas A Dumpling,4 February 1940,"9 October 2002, Laplata, Md"

关于python - 解析 HTML Python、BeautifulSoup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21662236/

相关文章:

postgresql - (PostgreSQL) 当 "column"中的所有日期都是来自另一个表的引用(外键)时,从 CSV 复制

python - 用于 Python 的 Nvidia-Docker API?

python - django 编码为 utf8 不工作

python - 如何使用 Blob 存储帐户在 azure-ml 中训练 YOLO-NAS 模型

javascript - 删除小屏幕/移动设备上的输入占位符,但在调整到桌面大小时再次添加它们

java - 使用 Java 在 CSV 中写入非拉丁字符

Python 和 MySQL 连接问题(mysqldb api)

javascript - 如何从使用 XMLHttpRequest 检索的 html 文档中获取图像?

python - 使用 BeautifulSoup 抓取特定的表行

sql - 如何从 CSV 获取文件名并将其插入表的列之一