我有一系列HTML文件,使用Beautiful Soup解析为单个文本文件。 HTML文件的格式使得它们的输出总是在文本文件中的三行,因此输出将类似于:
Hello!
How are you?
Well, Bye!
但它可以很容易
83957
And I ain't coming back!
hgu39hgd
换句话说,HTML文件的内容并不是每个文件的标准内容,但它们总是产生三行。
所以,我想知道如果我想要从Beautiful Soup生成的文本文件并将其解析为包含诸如(使用上面的示例)之类的列的CSV文件,我应该从哪里开始:
Title Intro Tagline
Hello! How are you? Well, Bye!
83957 And I ain't coming back! hgu39hgd
从文本文件中剥离HTML的Python代码是:
import os
import glob
import codecs
import csv
from bs4 import BeautifulSoup
path = "c:\\users\\me\\downloads\\"
for infile in glob.glob(os.path.join(path, "*.html")):
markup = (infile)
soup = BeautifulSoup(codecs.open(markup, "r", "utf-8").read())
with open("extracted.txt", "a") as myfile:
myfile.write(soup.get_text())
我收集我可以用它来设置我的CSV文件中的列:
csv.put_HasColumnNames(True)
csv.SetColumnName(0,"title")
csv.SetColumnName(1,"intro")
csv.SetColumnName(2,"tagline")
我绘制空白的地方是如何一次遍历文本文件(extracted.txt)一行,当我到达一个新行时,将其设置为CSV文件中的正确单元格。文件的前几行是空白的,每组文本之间有许多空行。所以,首先我需要打开文件并阅读它:
file = open("extracted.txt")
for line in file.xreadlines():
pass # csv.SetCell(0,0 X) (obviously, I don't know what to put in X)
另外,我不知道如何告诉Python只是继续阅读文件,并添加到CSV文件直到它完成。换句话说,没有办法确切知道HTML文件中的总行数,因此我不能只csv.SetCell(0,0) to cdv.SetCell(999,999)
答案 0 :(得分:6)
我不完全确定您使用的是哪个CSV库,但它看起来不像Python's built-in one。无论如何,这是我的方式:
import csv
import itertools
with open('extracted.txt', 'r') as in_file:
stripped = (line.strip() for line in in_file)
lines = (line for line in stripped if line)
grouped = itertools.izip(*[lines] * 3)
with open('extracted.csv', 'w') as out_file:
writer = csv.writer(out_file)
writer.writerow(('title', 'intro', 'tagline'))
writer.writerows(grouped)
这种管道。它首先从文件中获取数据,然后从行中删除所有空格,然后删除所有空行,然后将它们分组为三个组,然后(在写入CSV标题后)将这些组写入CSV文件。
要结合评论中提到的最后两列,您可以以显而易见的方式更改writerow
来电,将writerows
更改为:
writer.writerows((title, intro + tagline) for title, intro, tagline in grouped)
答案 1 :(得分:2)
也许我没有正确理解你,但你可以做到:
file = open("extracted.txt")
# if you don't want to do .strip() again, just create a list of the stripped
# lines first.
lines = [line.strip() for line in file if line.strip()]
for i, line in enumerate(lines):
csv.SetCell(i % 3, line)