【问题标题】:Using Beautifulsoup to find cell data, then print entire row if certain cell value is found使用 Beautifulsoup 查找单元格数据,如果找到某个单元格值,则打印整行
【发布时间】:2015-11-19 23:09:32
【问题描述】:

目前,我有一个如下所示的表格:

<tr class="tdc"><td class="myip_tdc"><a href="javascript:showIt('w115');">Account</a><br/><small>client</small></td>
<td class="tdc">Nov, 19 2015 05:18 pm </td>
<td class="tdc"><small><span style="color:green"> Check </span></small></td>
<tr class="tr"><td class="tde" colspan="6">
<div class="divl" id="wtt1266" style="display: block"><table><tr><td style="padding: 5px"><table><tr><td colspan="3"></td></tr><tr><td>
</td><td>

包含字符串“Check”的单元格是我要查找的单元格。我假设它正在寻找确切的字符串,所以也许我需要正则表达式来处理我确实 想要“检查”也算在内的事实。我什至还没有到达那里,但是如果有人有见解可以提供,我会接受!

所以,我有以下代码:

soup = BeautifulSoup(nextpage, "lxml") #page is now converted to a BeautifulSoup object
table = soup.find("table", {'class':'tbled'}) #here is our table
tablerow = soup.find("tr", {'class':"tr"}) #here is a single row of that table
tablecell = soup.find("td", {'class':'tdc'})

for line in tablerow:
    if line.find("Check"):
        print "Yay"

print line

因此,问题在于它正在打印所有单元格(很好),但在每一行之后都打印“Yay”。我只是希望它在带有“检查”的单个单元格之后打印“耶”。我认为 if 语句会解决这个问题,但我以某种方式搞砸了这个逻辑。有什么想法吗?

【问题讨论】:

  • 尝试if 'Check' in line:,因为line.find("Check")只有在字符串以Check开头时才会为假(因为索引将为0)。 .find() 如果没有找到则返回 -1,结果为真
  • 在我看来,如果您使用 lxml 模块而不是 beautifulsoup 并且花时间学习如何构建 XPATH 查询,它会更方便(并且更快)。我认为您在这里不需要正则表达式。
  • @RNar, "如果 'Check' in line:' 让我看不到 "yay" 打印输出,即使我可以在那里看到它。有什么想法吗?
  • 如果你把 print line 放在 for 循环中,你会打印每一行。这样做是为了确保您在设置tablerow 时获取了实际需要的数据。我觉得你可能不是

标签: python regex beautifulsoup


【解决方案1】:

如果你想转而使用正则表达式,这将是正则表达式

for line in tablerow:
     match = re.search("\bCheck\b", line)
     if match:
         print "Yay"

这将匹配 Check 但不匹配 Checked

或者如果你不希望它是特定的情况

for line in tablerow:
     match = re.search("\b.heck\b", line)
     if match:
         print "Yay"

也可以

【讨论】:

  • 但是Sheck呢?! (开玩笑)但我建议改为[Cc] 而不是.
  • 哈哈,其实我也想过同一个词。我使用“。”的原因。而不是 Cc 是在 regex101 上找到匹配项所需的步骤更少(尽管只有几个,但我喜欢尝试找到尽可能少的步骤,我认为 sheck 的概率相当低:p)
  • 嗯,这似乎不起作用。它在找到 Check 后不会打印“yay”,即使我正在查看它......
  • 使用此代码找出 tablerow 中的行......... print line ... 将其放在行之前 ..... match = re.search ("\bCheck\b", 行)
  • 我想你会想要使用 tablecell 而不是 tablerow
【解决方案2】:

有多种方法可以解决问题。

一个想法是将function as a text argument value 传递给find() 方法。该函数将剥离元素的文本并将其与Check 进行比较。然后,一旦找到元素,我们就可以在树中向上和find the parent td 元素:

elm = soup.find(text=lambda x: x and x.strip() == "Check")
td = elm.find_parent("td", class_="tdc")

为了扩展@Nefarii 的答案,您可以通过以下方式应用有界正则表达式:

elm = soup.find(text=re.compile(r"\b[Cc]heck\b"))
td = elm.find_parent("td", class_="tdc")

【讨论】:

  • 嗯,如果我打印它,榆树会给我“无”。 for line in tablerow: elm = soup.find(text=lambda x: x and x.strip() == "Check") print elm
  • @SamW 我认为您正在寻找错误的地方 - tablerow 包含带有 class="tr" 的行,而带有 Check 文本的元素在 trclass="tdc" 内。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多