【问题标题】:how to convert a bs4.element.ResultSet to strings? Python如何将 bs4.element.ResultSet 转换为字符串? Python
【发布时间】:2014-01-24 22:54:34
【问题描述】:

我有一个简单的代码,例如:

    p = soup.find_all("p")
    paragraphs = []

    for x in p:
        paragraphs.append(str(x))

我正在尝试转换从 xml 获得的列表并将其转换为字符串。我想保留它的原始标签,这样我就可以重用一些文本,这就是我这样附加它的原因。但是该列表包含超过 6000 个观察值,因此由于 str:

而发生递归错误

“RuntimeError: 调用 Python 对象时超出最大递归深度”

我读到您可以更改最大递归,但这样做并不明智。我的下一个想法是将转换为字符串分成 500 个批次,但我确信必须有更好的方法来做到这一点。有人有什么建议吗?

【问题讨论】:

  • 您能否将示例 xml 文件发布到 pastebin 或其他内容(如有必要,删除敏感数据)?我无法理解为什么只在 <p> 元素上调用 str 会导致递归深度错误,除非您将标签嵌套到接近 500 的深度。
  • 我使用的是公共数据。该文件可以在这里找到sec.gov/Archives/edgar/data/1547063/000119312513465948/…。正如我在描述中提到的那样,p 中有超过 6000 个段落标签
  • 导致问题的原因是文档底部的二进制图形块,其中一些包含序列<P,我认为BeautifulSoup 正试图将其修复为实际的XML 标记。你需要图形块吗?
  • @senshin:不,beautifulsoup 效果很好。问题在于将每个单独的标签转换为字符串,从而给了我一个 runtimeErorr
  • 好的,如果你认为这是问题所在,试试这个:在你的 for 循环中添加一个计数器,在每次迭代时,将计数器加一并打印出计数器的值。告诉我RuntimeError 发生时计数器的值是多少。

标签: python beautifulsoup runtime-error


【解决方案1】:

我认为问题在于BeautifulsSoup 对象p 未构建iteratiely,因此在您可以完成构建p = soup.find_all('p') 之前达到method call limit。请注意,RecursionError 在构建 soup.prettify() 时同样会抛出。

对于我的解决方案,我使用了re 模块来收集所有<p>...</p> 标签(参见下面的代码)。我的最终结果是len(p) = 5571。此计数低于您的计数,因为正则表达式条件与二进制图形数据中的任何文本都不匹配。

import re
import urllib
from urllib.request import Request, urlopen

url = 'https://www.sec.gov/Archives/edgar/data/1547063/000119312513465948/0001193125-13-465948.txt'

response = urllib.request.urlopen(url).read()
p = re.findall('<P((.|\s)+?)</P>', str(response)) #(pattern, string)

paragraphs = []
for x in p:
    paragraphs.append(str(x))

【讨论】:

  • 使用对象.__str__()方法不是更好吗?所以x.__str__()
【解决方案2】:

这里的问题可能是the document底部的一些二进制图形数据包含&lt;P的字符序列,Beautiful Soup正试图将其修复为实际的HTML标签。我还没有设法查明哪个文本导致“超出递归深度”错误,但它就在那里。对我来说是p[6053],但是由于您似乎对文件进行了一些修改(或者您可能对 Beautiful Soup 使用了不同的解析器),我想这对您来说会有所不同。

假设您不需要文档底部的二进制数据来从 actual &lt;p&gt; 标签中提取您需要的任何内容,试试这个:

# boot out the last `<document>`, which contains the binary data
soup.find_all('document')[-1].extract()

p = soup.find_all('p')
paragraphs = []
for x in p:
    paragraphs.append(str(x))

【讨论】:

  • 我也在将此代码用于其他文档,所以我不认为丢弃最后一个文档是最好的选择,但你正在引导我走上正确的道路。
  • 您需要采用一种策略,该策略基本上涉及查看每个&lt;DOCUMENT&gt;&lt;TYPE&gt; 并消除&lt;TYPE&gt;GRAPHIC 的那些。这不会很优雅,因为数据文件有非常畸形的标签,但它应该可以工作。您也可以尝试检查begin 644,它仅出现在GRAPHIC 文档中。作为最后的手段,尝试将数据文件中的 &lt;HTML&gt;...&lt;/HTML&gt; 重命名为 &lt;HTMLTWO&gt;...&lt;/HTMLTWO&gt;,然后仅迭代 soup.find_all('htmltwo') 而不是整个汤。
  • @samuraiexe 如果数据文件的非GRAPHICS 部分的文本包含一些您正在过滤的相同字符串,那么所有这些都可能会失败,但我认为这是您的问题将不得不忍受。
猜你喜欢
  • 1970-01-01
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
  • 2018-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多