python - 从python中的网页集合中抓取html标签的快速方法

标签 python html web-scraping beautifulsoup xmlstarlet

我试图从包含 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>' ),但是:
  • 这个过程非常缓慢
  • 无论出于何种原因<转化为 &lt; , 为了摆脱它,我发现没有比解码更简单的方法 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/

    相关文章:

    python - 遍历 csv/xlsx 文件 python 3 中的行和列

    python - 值错误 : First argument must be a sequence ----> Scatter Plot Python

    python - pycharm 在启动时总是 "uploading pycharm helpers"到同一个远程 python 解释器

    javascript - 使用输入值创建变量 javascript

    python - 使用 click() webdriver selenium 函数 Python 时超时

    python - 如何让 Python 打印文件的内容

    html - 创建定时图像幻灯片放映,其中每个图像都是一个链接?

    Javascript: 弹出框,如果点击 "Don' t 显示不显示"

    Python - 从谷歌图片搜索下载图片?

    python - 网页抓取到 html 中的特定点然后停止