我试图从一个包含html文档集合的.gz文件中检索内容,这是一个来自GOV2集合的文件,每个页面由标签分隔,每个标签包含几个元信息,其中包括文档的id和(或),其内容。每个页面由标签分开,每个标签包含几个元信息,其中包括文档的id和(或),它的内容。
<doc>
<docno>GX000-xx-xxxxxxx</docno>
<dochdr>
<!-- no relevant meta info -->
</dochdr>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<html>
<!-- the content I want to extract -->
</html>
</doc>
<doc>
<docno>GX000-xx-xxxxxxy</docno>
<dochdr>
<!-- no relevant meta info -->
</dochdr>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<html>
<!-- another content I want to extract -->
</html>
</doc>
我需要一个列表,其中包含每个 docno
和每个html标签的内容分别。
这是我用BeautifulSoup做的。
doc_file = 'xx.gz'
f = gzip.open(data_dir + doc_file)
doc_string = f.read()
f.close()
soup = BeautifulSoup(doc_string, "html.parser")
doc_list = soup.select('DOC')
doc_no = []
doc_content = []
for doc in doc_list:
doc_no.append(doc.find('docno').get_text())
doc_raw = doc.find('html')
if doc_raw is None: #It's possible a doc has no html tag
doc_content.append('<null/>')
else:
doc_content.append(re.sub(r'(\n\s*)+\n+', '\n', doc.find('html').get_text()))
这个方法很好用,但是html.parser是个很慢的解析器(每个文件大约4分钟,但是我有几千个文件要刮......)。幸运的是,使用另一个解析器,如 lxml
. 然而,这样的解析器,无论出于什么原因,都会删除掉 <html>
标签。我尝试了另一种方法,在 doc_string 中替换了这些标签(使用 doc_string=doc_string.replace(b'<html>', b'<2html>'
)才调用BeautifulSoup,但。
这个过程很慢
不知为何 <
变成了 <
要解开它,我发现没有比解码更简单的方法了。doc_string
,解开它,然后重新编码,这在时间上是荒谬的。即使直接替换 b'html'
每 b'2html'
似乎逃不过 <
和 >
你有什么更快的方法来完成这样的任务吗?
谢谢你的帮助,我想从一个包含html文档集合的.gz文件中检索内容,这是一个GOV2集合的文件。
正如我在帖子中所说的,我认为将文档转换为字符串,然后替换为 html
标签,然后再将字符串重新编码为字节就太长了。事实证明我错了。
在搞清楚这个问题后,我采用的策略是把每一个的 html
由另一个独特的词出现(不仅是标签)(比如下面的与 htmltag
). 然后有一次,我把一个的内容废掉了。htmltag
,我将剩下的每一个出现的 htmltag
回到 html
. 这样一来,内容完全不会被改变。
f = gzip.open(data_dir + doc_file)
doc_string = f.read()
f.close()
doc_string_str = doc_string.decode(errors='ignore')
doc_string_str = doc_string_str.replace('html', 'htmltag')
doc_string = doc_string_str.encode()
soup = BeautifulSoup(doc_string, "lxml")
doc_list = soup.select('DOC')
doc_no = []
doc_content = []
for doc in doc_list:
doc_no.append(doc.find('docno').get_text())
doc_raw = doc.find('htmltag')
if doc_raw is None: #It's possible a doc has no html tag
doc_content.append('<null/>')
else:
doc_content.append(re.sub(r'(\n\s*)+\n+', '\n', doc.find('htmltag').get_text()).replace('htmltag', 'html'))
感谢@shellter和@JL_Peyret的帮助,我基本上是按照你们告诉我的,但是直接用Python来做。据了解,每个文档大约需要15秒。