2012-08-04 39 views
5
html = """ 
... 
<tt class="descname">all</tt> 
<big>(</big> 
<em>iterable</em> 
<big>)</big> 
<a class="headerlink" href="#all" title="Permalink to this definition">¶</a> 
... 
""" 

Tôi muốn nhận tất cả văn bản giữa thẻ bắt đầu big tối đa trước khi xuất hiện lần đầu tiên thẻ a. Điều này có nghĩa là nếu tôi lấy ví dụ này, thì tôi phải nhận được (iterable) làm chuỗi.Làm cách nào để nhận tất cả văn bản giữa hai thẻ được chỉ định bằng cách sử dụng BeautifulSoup?

Trả lời

3

tôi sẽ tránh nextSibling, kể từ câu hỏi của bạn, bạn muốn bao gồm tất cả mọi thứ cho đến tiếp theo <a>, bất kể đó là trong phần tử anh chị em, cha mẹ hoặc con.

Vì vậy, tôi nghĩ cách tiếp cận tốt nhất là tìm nút là phần tử <a> tiếp theo và lặp lại cho đến lúc đó, thêm mỗi chuỗi như đã gặp phải. Bạn có thể cần phải dọn dẹp phần bên dưới nếu HTML của bạn khác với mẫu, nhưng một cái gì đó như thế này sẽ hoạt động:

from bs4 import BeautifulSoup 
#by taking the `html` variable from the question. 
html = BeautifulSoup(html) 
firstBigTag = html.find_all('big')[0] 
nextATag = firstBigTag.find_next('a') 
def loopUntilA(text, firstElement): 
    text += firstElement.string 
    if (firstElement.next.next == nextATag):    
     return text 
    else: 
     #Using double next to skip the string nodes themselves 
     return loopUntilA(text, firstElement.next.next) 
targetString = loopUntilA('', firstBigTag) 
print targetString 
+0

vâng, chính xác, tôi muốn bao gồm mọi thứ tối đa thẻ tiếp theo 'a' và có thể có bất kỳ số lượng thẻ, văn bản nào giữa thẻ 'lớn' đầu tiên và thẻ 'a' đầu tiên –

0
>>> from BeautifulSoup import BeautifulSoup as bs 
>>> parsed = bs(html) 
>>> txt = [] 
>>> for i in parsed.findAll('big'): 
...  txt.append(i.text) 
...  if i.nextSibling.name != u'a': 
...   txt.append(i.nextSibling.text) 
... 
>>> ''.join(txt) 
u'(iterable)' 
+0

'nextiSbling' không thể được sử dụng như tôi muốn bao gồm tất cả các văn bản tối đa sự xuất hiện đầu tiên của thẻ 'a' –

1

bạn có thể làm như thế này:

from BeautifulSoup import BeautifulSoup 
html = """ 
<tt class="descname">all</tt> 
<big>(</big> 
<em>iterable</em> 
<big>)</big> 
<a class="headerlink" href="test" title="Permalink to this definition"></a> 
""" 
soup = BeautifulSoup(html) 
print soup.find('big').nextSibling.next.text 

Để biết chi tiết kiểm tra dom đi qua với BeautifulSoup từ here

+0

này trả về "iterable" chứ không phải "(iterable)" – anotherdave

5

Cách tiếp cận lặp lại.

from BeautifulSoup import BeautifulSoup as bs 
from itertools import takewhile, chain 

def get_text(html, from_tag, until_tag): 
    soup = bs(html) 
    for big in soup(from_tag): 
     until = big.findNext(until_tag) 
     strings = (node for node in big.nextSiblingGenerator() if getattr(node, 'text', '').strip()) 
     selected = takewhile(lambda node: node != until, strings) 
     try: 
      yield ''.join(getattr(node, 'text', '') for node in chain([big, next(selected)], selected)) 
     except StopIteration as e: 
      pass 

for text in get_text(html, 'big', 'a'): 
    print text 
Các vấn đề liên quan