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