首页 > 解决方案 > 从 kworb.net 抓取数据时,if 条件不在 for 循环中执行

问题描述

我需要收集有关艺术家在 Spotify 上播放频率最高的国家/地区的数据。为此,我正在使用包含 10.000 位艺术家列表的源。

所以我的代码的目的是创建一个包含两列的表:

  1. 艺术家姓名;
  2. 艺术家流媒体最多的国家。

我编写了一个代码(见下文),从每个艺术家的个人页面(这里是Drake的示例)获取此信息。艺术家的名字取自页面标题和国家代码——取自标题为“全球”的列前面的表列标题。对于一些艺术家来说,没有标题为“全球”的栏目,我需要考虑这种情况。这就是我的问题所在。

我正在使用以下 if 条件:

if "<th>Global</th>" not in soup2.find_all('table')[0].find_all('th'):
    Country = soup2.find_all('table')[0].find_all('th')[4].text
else:
    Country = soup2.find_all('table')[0].find_all('th')[5].text
country.append(Country)

但只执行第一个条件,代码从第 4 列中提取文本。或者,我尝试了相反的条件:

if "<th>Global</th>" in soup2.find_all('table')[0].find_all('th'):
    Country = soup2.find_all('table')[0].find_all('th')[5].text
else:
    Country = soup2.find_all('table')[0].find_all('th')[4].text
country.append(Country)

但是代码仍然从第 4 列中提取文本,即使我希望它在第 4 列标题为“全局”时从第 5 列中提取它。

这个可重现的代码是为一部分艺术家运行的,他们有一个标题为“全球”的列(例如LANY)而没有列(例如Henrique 和 Diego)(截至 2019 年 6 月 16 日的#391 到 #395) :

from time import sleep
from random import randint
from requests import get
from bs4 import BeautifulSoup as bs
import pandas as pd

response1 = get('https://kworb.net/spotify/artists.html', headers = headers)

soup1 = bs(response1.text, 'html.parser')
table = soup1.find_all('table')[0]
rows = table.find_all('tr')[391:396]    #selected subset of 10.000 artists

artist = []
country = []

for row in rows:
    artist_url = row.find('a')['href']

    response2 = get('https://kworb.net/spotify/' + artist_url)

    sleep(randint(8,15))

    soup2 = bs(response2.text, 'html.parser')

    Artist = soup2.find('title').text[:-24]
    artist.append(Artist)

    if "<th>Global</th>" not in soup2.find_all('table')[0].find_all('th'):    #problem suspected in this if-condition
        Country = soup2.find_all('table')[0].find_all('th')[4].text
    else:
        Country = soup2.find_all('table')[0].find_all('th')[5].text
    country.append(Country)

df = pd.DataFrame({'Artist': artist,
                   'Country': country
})

print(df)

结果,我得到以下信息:

    Artist           Country
0   YNW Melly        Global
1   Henrique & Diego BR
2   LANY             Global
3   Parson James     Global
4   ANAVITÃRIA       BR

而截至 2019 年 6 月 16 日的实际产出应该是:

    Artist              Country
0   YNW Melly           US
1   Henrique & Diego    BR
2   LANY                PH
3   Parson James        US
4   ANAVITÃRIA          BR

我怀疑变量的 if-condition 错误country。我将不胜感激这方面的任何帮助。

标签: pythonif-statementweb-scraping

解决方案


您将 bs4 对象与字符串进行比较。需要首先从每个找到的对象中获取文本,然后与字符串进行比较:

代替:

if "<th>Global</th>" not in soup2.find_all('table')[0].find_all('th'):

和:

# get text options from html
found_options = [item.text for item in soup2.find_all('table')[0].find_all('th')]

if "Global" not in found_options:

输出:

             Artist Country
0         YNW Melly      US
1  Henrique & Diego      BR
2              LANY      PH
3      Parson James      US
4       ANAVITÃRIA      BR

推荐阅读