BeautifulSoup find_all除了最后四个之外

时间:2014-11-17 19:58:39

标签: python beautifulsoup

我试图从所有细胞中删除所有文本,除了最后四个细胞。有没有办法做到这一点,还是我应该尝试找到问题的另一种解决方案?我的代码目前非常简单:

import requests
from bs4 import BeautifulSoup

r = requests.get("http://www.example.com/")
soup = BeautifulSoup(r.content)
for link in soup.find_all("td"):
    print(link.string)

谢谢!

2 个答案:

答案 0 :(得分:2)

find_all()返回基于ResultSet的{​​{1}}对象:

list

Slice它:

class ResultSet(list):
    """A ResultSet is just a list that keeps track of the SoupStrainer
    that created it."""
    def __init__(self, source, result=()):
        super(ResultSet, self).__init__(result)
        self.source = source

答案 1 :(得分:1)

如果你想迭代地这样做,而不将整个结果集加载到列表中,你可以。只需保留4个链接的队列,当队列已满时,弹出并打印最旧的,然后再按最新的。像这样:

q = collections.deque(maxlen=4)
for link in soup.find_all("td"):
    if len(q) == q.maxlen:
        print(q.popleft())
    q.push(link.string)

当然,你可以将它包装在一个函数中:

def butlast(iterable, n):
    q = collections.deque(maxlen=n)
    for value in iterable:
        if len(q) == q.maxlen:
            yield q.popleft()
        q.push(value)

for link in butlast(soup.find_all("td"), 4):
    print(link.string)

但实际上,如果你有足够的内存来存储整个Soup,你可能已经有足够的内存来存储几十个节点的列表,所以这是一个更容易使用列表的列表。事实证明,soup.find_all()已经返回了一个列表(好吧,list的子类),所以你只需要这样做:

for link in soup.find_all("td")[:-4]:
    print(link.string)

但是,即使这不是真的,你也可以制作一个列表来切片:

for link in list(soup.find_all("td"))[:-4]:
    print(link.string)