0

我有一个具有以下格式的文本文件,我正在尝试获取<doc>标签之间的文本。但是<doc>标签重复了很多次,并且文件不是标准的 xml 或 html 格式,这会导致问题。

格式:

<doc id = "some_number" url = " some_link " title = " some_title " >

text here

</doc>//然后再一次

<doc id = "some_number" url = " some_link " title = " some_title " >

text here

</doc> // 等等

我试图在 python 中使用 Beautiful soup 获取文本,但它说这个对象不可调用,我猜这是因为它不是 html 文件格式。此外,我尝试使用正则表达式,所以我写了

pattern = re.compile("<doc.*?>(.*?)</doc>")

pattern.findall(string_text) # string_text is my file

但找不到匹配项。

谢谢你的帮助。

4

2 回答 2

2

您的 HTML 没有明显的错误,BeautifulSoup 也没有理由不能解析它。例如:

from bs4 import BeautifulSoup

s = '''
<doc id = "some_number" url = " some_link " title = " some_title " >

text here

</doc>

<doc id = "some_number" url = " some_link " title = " some_title " >

text here

</doc>'''

soup = BeautifulSoup(s)
for doc in soup.find_all('doc'):
    print('{}: {}'.format(doc['title'], doc.text))

当我运行它时,它显示的内容如下:

 some_title :
text here

 some_title :
text here

如果我留下您在问题中的 C++ 样式注释,但在代码部分之外,它也可以工作。


如果“它说这个对象是不可调用的”,那么你的代码显然做错了。例如,如果我这样做:

for doc in soup.find_all('doc'):
    doc['title']('text')

……它当然会引发:

TypeError: 'str' object is not callable

但这并不是因为 BS 无法解析 HTML,而是因为我从 BS 中得到了一个字符串并试图将其作为函数调用。

我不知道实际上做错了什么,因为你没有向我们展示代码,甚至你得到的确切错误。


同时,如果您想知道您的 HTML 出了什么问题,那么存在三个问题。

第一个问题是您无法使用 regexp 解析 HTML

第二个问题是你试图使用.*?匹配,除其他外,换行符,并且就在文档的最顶部附近re,它说:

'.'

(点。)在默认模式下,这匹配除换行符以外的任何字符。如果指定了 DOTALL 标志,则它匹配任何字符,包括换行符。

所以,你需要pattern = re.compile("<doc.*?>(.*?)</doc>", re.DOTALL).

但是,如果 adoc可以有另一个doc内部,或者如果您可以在引号中包含任何会让您感到困惑的字符,或者如果......好吧,这可能会失败的原因有很多。这就是为什么:

第三个问题是您没有阅读You can't parse HTML with regexp,您需要阅读它。

于 2013-10-07T21:56:35.393 回答
1
your_doc = """
         <doc id = "some_number" url = " some_link " title = " some_title " >
         text here
         </doc> //then again

         <doc id = "some_number" url = " some_link " title = " some_title " >
         text here
         </doc>
         """
from bs4 import BeautifulSoup as b

soup = b(your_doc)

specific_doc = b.find('doc', {'id': 'some number'}) #to get a doc with given id. 
print specific_doc.contents #printing the text

all_docs = b.findAll('docs') # list of all doc tags.
for doc in all_docs: #printing all the texts
    print 'Text in doc id:', doc['id']
    print doc.contents
于 2013-10-07T22:01:29.273 回答