ɥɔǝ*_*loɥ 33 python beautifulsoup
我尝试从以下HTML中提取"这是我的文本":
<html>
<body>
<table>
<td class="MYCLASS">
<!-- a comment -->
<a hef="xy">Text</a>
<p>something</p>
THIS IS MY TEXT
<p>something else</p>
</br>
</td>
</table>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我这样试过:
soup = BeautifulSoup(html)
for hit in soup.findAll(attrs={'class' : 'MYCLASS'}):
print hit.text
Run Code Online (Sandbox Code Playgroud)
但我得到所有嵌套标签和评论之间的所有文本.
任何人都可以帮助我从中获得"这是我的文字"吗?
kir*_*off 35
详细了解如何浏览解析树BeautifulSoup
.解析树得到了tags
和NavigableStrings
(因为这是一个文本).一个例子
from BeautifulSoup import BeautifulSoup
doc = ['<html><head><title>Page title</title></head>',
'<body><p id="firstpara" align="center">This is paragraph <b>one</b>.',
'<p id="secondpara" align="blah">This is paragraph <b>two</b>.',
'</html>']
soup = BeautifulSoup(''.join(doc))
print soup.prettify()
# <html>
# <head>
# <title>
# Page title
# </title>
# </head>
# <body>
# <p id="firstpara" align="center">
# This is paragraph
# <b>
# one
# </b>
# .
# </p>
# <p id="secondpara" align="blah">
# This is paragraph
# <b>
# two
# </b>
# .
# </p>
# </body>
# </html>
Run Code Online (Sandbox Code Playgroud)
要向下移动你解析树contents
和string
.
contents是页面元素中包含的Tag和NavigableString对象的有序列表
如果一个标签只有一个子节点,并且该子节点是一个字符串,则该子节点可用作tag.string,以及tag.contents [0]
对于上述情况,也就是说你可以得到
soup.b.string
# u'one'
soup.b.contents[0]
# u'one'
Run Code Online (Sandbox Code Playgroud)
例如,对于多个子节点,您可以使用
pTag = soup.p
pTag.contents
# [u'This is paragraph ', <b>one</b>, u'.']
Run Code Online (Sandbox Code Playgroud)
所以你可以在这里玩,contents
并获得你想要的索引的内容.
您还可以迭代标记,这是一个快捷方式.例如,
for i in soup.body:
print i
# <p id="firstpara" align="center">This is paragraph <b>one</b>.</p>
# <p id="secondpara" align="blah">This is paragraph <b>two</b>.</p>
Run Code Online (Sandbox Code Playgroud)
Ter*_*ryA 14
你可以使用.contents
:
>>> for hit in soup.findAll(attrs={'class' : 'MYCLASS'}):
... print hit.contents[6].strip()
...
THIS IS MY TEXT
Run Code Online (Sandbox Code Playgroud)
Mar*_*ers 13
.children
改为使用:
from bs4 import NavigableString, Comment
print ''.join(unicode(child) for child in hit.children
if isinstance(child, NavigableString) and not isinstance(child, Comment))
Run Code Online (Sandbox Code Playgroud)
是的,这有点像舞蹈.
输出:
>>> for hit in soup.findAll(attrs={'class' : 'MYCLASS'}):
... print ''.join(unicode(child) for child in hit.children
... if isinstance(child, NavigableString) and not isinstance(child, Comment))
...
THIS IS MY TEXT
Run Code Online (Sandbox Code Playgroud)
Gre*_*ler 10
用你自己的汤对象:
soup.p.next_sibling.strip()
Run Code Online (Sandbox Code Playgroud)
soup.p
*抓住<p> (这取决于它是解析树中的第一个<p>)next_sibling
的标记对象,soup.p
因为所需的文本嵌套在与<p>相同的解析树级别.strip()
只是一个Python str方法来删除前导和尾随空格在解释器中,这看起来像:
In [4]: soup.p
Out[4]: <p>something</p>
In [5]: type(soup.p)
Out[5]: bs4.element.Tag
In [6]: soup.p.next_sibling
Out[6]: u'\n THIS IS MY TEXT\n '
In [7]: type(soup.p.next_sibling)
Out[7]: bs4.element.NavigableString
In [8]: soup.p.next_sibling.strip()
Out[8]: u'THIS IS MY TEXT'
In [9]: type(soup.p.next_sibling.strip())
Out[9]: unicode
Run Code Online (Sandbox Code Playgroud)
简短回答: soup.findAll('p')[0].next
真实答案:您需要一个不变的参考点,您可以从中获得目标.
你在评论中提到了海德罗的答案,你想要的文字并不总是在同一个地方.找到一种相对于某个元素位于同一位置的感觉.然后弄清楚如何使BeautifulSoup在该不变路径之后导航解析树.
例如,在原始帖子中提供的HTML中,目标字符串紧跟在第一个段落元素之后,并且该段落不为空.既然findAll('p')
会找到段落元素,那soup.find('p')[0]
将是第一段元素.
你可以在这种情况下使用soup.find('p')
但soup.findAll('p')[n]
更通用,因为你的实际场景可能需要第5段或类似的东西.
该next
字段属性将在树中,包括儿童在内的下一个解析的元素.因此soup.findAll('p')[0].next
包含段落的文本,并将soup.findAll('p')[0].next.next
在提供的HTML中返回您的目标.
归档时间: |
|
查看次数: |
138219 次 |
最近记录: |