BeautifulSoup - 在过滤掉 <td> 的同时查找 <a> 可能吗?

问题描述 投票:0回答:2

我在抓取某个网站时遇到了一些麻烦,因为大部分信息都被奇怪地掩埋了,而且表格大小也不一致。

这里是 HTML 的例子:

<tbody>
    <tr>
        <td>
            <a href="LINK">Player1</a>
        </td>
        <td>Position1</td>
        <td>
            <b>Player1 Injury</b>
            <br>
            "Date of injury1"
        </td>
        <td>
            <a href="LINK" class="BUTTON"></a>
        </td>
    </tr>
    <tr class="COLLAPSE"></tr>
    <tr>
        <td>
            <a href="LINK">Player2</a>
        </td>
        <td>Position2</td>
        <td>
            <b>Player2 Injury</b>
            <br>
            "Date of injury2"
        </td>
        <td>
            <a href="LINK" class="BUTTON"></a>
        </td>
    </tr>
    <tr class="COLLAPSE"></tr>
</tbody>

鉴于这些数据,我要做的就是用玩家的受伤情况和受伤日期来提取

<td>

如果我做一个

injury.find_all('td')

当然,我会得到所有我不想要的额外数据。我想要提取的所有数据将始终位于第 3 个

<td>
标签中,但我还需要在新标签中再次找到第 3 个
<td>
标签。过滤掉
class="COLLAPSE"
应该很容易实现,希望不会成为问题。

所以,抓取这些数据的结果,我想要的结果是:

['Player1 Injury', 'Date of injury1', 'Player2 Injury', 'Date of injury2']

非常感谢所有帮助。

python web-scraping beautifulsoup findall
2个回答
0
投票

感谢发布

html
。以此为例,我认为我们需要遍历
<tr>
标签中的每个
<tbody>
标签,检查它是否具有“COLLAPSE”类。

如果

<tr>
标签没有“COLLAPSE”类,那么你可以找到它里面所有的
<td>
标签并提取第三个标签(索引2),其中包含球员的受伤情况和他们受伤的日期。

代码如下:

from bs4 import BeautifulSoup

# HTML code
html = """
<tbody>
    <tr>
        <td>
            <a href="LINK">Player1</a>
        </td>
        <td>Position1</td>
        <td>
            <b>Player1 Injury</b>
            <br>
            "Date of injury1"
        </td>
        <td>
            <a href="LINK" class="BUTTON"></a>
        </td>
    </tr>
    <tr class="COLLAPSE"></tr>
    <tr>
        <td>
            <a href="LINK">Player2</a>
        </td>
        <td>Position2</td>
        <td>
            <b>Player2 Injury</b>
            <br>
            "Date of injury2"
        </td>
        <td>
            <a href="LINK" class="BUTTON"></a>
        </td>
    </tr>
    <tr class="COLLAPSE"></tr>
</tbody>
"""

# Parse the HTML
soup = BeautifulSoup(html, 'html.parser')

# Find all <tr> tags within the <tbody> tag
trs = soup.tbody.find_all('tr')

# Extract the player's injury and the date of their injury from each <tr> tag
injuries = []
for tr in trs:
    if not tr.has_attr('class') or 'COLLAPSE' not in tr['class']:
        tds = tr.find_all('td')
        injury = tds[2].b.get_text().strip()
        date = tds[2].find_all('br')[-1].next_sibling.strip()
        injuries.append(injury)
        injuries.append(date)

print(injuries) 

# Output: ['Player1 Injury', 'Date of injury1', 'Player2 Injury', 'Date of injury2']

0
投票

一切都在第三个

td
里面一个
tr
tbody
。然后我们可以得到第一个
<b>
标签和最后一个孩子(这是一个文本节点)。然后使用
.strip()
去掉空格和换行符,第二条去掉
"
(如果你没有看到这些引号,你可以删除这个
.strip
)。

data = [
    item
    for injury in soup.select("tbody > tr > td:nth-of-type(3)")
    for item in [injury.find("b").text, list(injury)[-1].text.strip().strip('"')]
]

输出

['Player1 Injury', 'Date of injury1', 'Player2 Injury', 'Date of injury2']
© www.soinside.com 2019 - 2024. All rights reserved.