BeautifulSoup 指定元素和类名后不定位任何内容

BeautifulSoup not targeting anything after specifying the element and classname

我正在尝试抓取此网站 https://en.wikipedia.org/wiki/Korean_drama. Specifically the list of highest rated Korean dramas in cable television. This is what inspect element looks like

这是我的代码

import requests
from bs4 import BeautifulSoup

url = 'https://en.wikipedia.org/wiki/Korean_drama'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
kdramas = soup.find_all(
    'table', class_="wikitable sortable jquery-tablesorter")
print(kdramas)
for kdrama in kdramas:
    print(kdrama.text)

这是我 运行 我的代码

时发生的情况
admins-MBP:~ admin$ python3 kdramas.py
[]

我认为指定的代码没有问题。

我的建议是尝试层次结构中更高层的其他标签并观察输出。不同的网站有不同的标签和 类 所以没有一个解决所有问题的方法。也许首先尝试在层次结构中更高的 div 标签。

我认为 jquery-tablesorter class 可以动态添加,这就是 BeautifulSoup 无法读取它的原因。

我的建议是选择引入 table 的 h3 标签,然后深入研究 DOM 中的第一个 table 对象。

类似于:

# h3 tag name is actually in a <span> inside the h3 element
table_lead_in = soup.find('span', id="List_of_highest-rated_Korean_dramas_in_public_broadcast")

for drama_table in table_lead_in.find_next('tbody'):
    for tr in drama_table.find_all_next('tr'):
        rank = tr.find('td').text
        title = tr.find('a').text
        print(f"Title: {title} ** Rank: {rank}")

输出:

Title: You and I ** Rank: 1
Title: First Love ** Rank: 2
Title: What Is Love ** Rank: 3
Title: Sandglass ** Rank: 4
Title: Hur Jun ** Rank: 5
Title: A Sunny Place of the Young ** Rank: 6
Title: Sons and Daughters ** Rank: 7

(注意:find() 调用中包含一些懒惰的假设,但出于演示目的,这应该足够了。)

class wikitable sortable jquery-tablesorter 有时被命名为 wikitable sortable。 您可以使用 CSS select 或 select 以 wikitable sortable 开头的 class,这两种情况都适用:

import requests
from bs4 import BeautifulSoup

url = 'https://en.wikipedia.org/wiki/Korean_drama'

response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
kdramas = soup.select_one('table[class^="wikitable sortable"]:nth-of-type(2)')

for row in kdramas.select('tr'):
    data = [td.get_text(strip=True) for td in row.select('td')]
    print(' '.join('{: <30}'.format(d) for d in data))