我试图从包含 html 文档集合的 .gz 文件中检索内容,它是来自 GOV2 集合的文件。每个页面由标签分隔,每个标签包含几个元信息,其中包括文档的 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>
标签。我尝试了另一种方法,在调用 BeautifulSoup 之前,我在 doc_string 中替换了这些标签(使用 doc_string=doc_string.replace(b'<html>', b'<2html>'
),但是:<
转化为 <
, 为了摆脱它,我发现没有比解码更简单的方法 doc_string
,转义它,然后重新编码它,这在时间上是荒谬的。甚至直接更换b'html'
每 b'2html'
似乎逃过了<
和 >
你有更快的方法来完成这样的任务吗?
感谢您的帮助。
最佳答案
正如我在帖子中所说,我想将文档转换为字符串,然后替换 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 秒。
关于python - 从python中的网页集合中抓取html标签的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62322881/