【问题标题】:Webscraping with a loop returns only a single element带有循环的 Web Scraping 仅返回单个元素
【发布时间】:2021-08-05 09:15:18
【问题描述】:

当我运行 for 循环来收集 <div> 标记中的元素时,它只返回具有相同 class 的所有列表中的第一个。

例如:

r = requests.get("https://one-versus-one.com/en/rankings/all/statistics")

soup = BeautifulSoup(r.content, 'lxml')

data = {
    'players': [],
    'club': [],
    'rank': []
}
def getstuff(soup):
    products = soup.find_all('div', {'class':'rankings-table'})
    for name in products:
        players = name.find('div', {'class':'player-name rankings-table__player-name'}).text
        club = name.find('span', {'class':'rankings-table__club-name'}).text
        rank = name.find('div', {'class':'rankings-table-cell value rankings-table__value'}).text.strip()
        data['players'] = players
        data['club'] = club
        data['rank'] = rank
        print(data)

getstuff(soup)

这会返回:

{'players': 'Lionel Messi', 'club': 'Barcelona', 'rank': '100'}

我希望所有球员、俱乐部和排名都打印在页面中。

【问题讨论】:

    标签: python web-scraping


    【解决方案1】:

    你可以试试这个:

    import requests
    from bs4 import BeautifulSoup
    
    r = requests.get("https://one-versus-one.com/en/rankings/all/statistics")
    soup = BeautifulSoup(r.content, 'lxml')
    
    data = {'players': [],'club': [],'rank': []}
    
    def getstuff(soup):
        products = soup.find('div', {'class':'rankings-table'}).find_all("a")
        for name in products:
            players = name.find('div', {'class':'player-name rankings-table__player-name'}).text
            club = name.find('span', {'class':'rankings-table__club-name'}).text
            rank = name.find('div', {'class':'rankings-table-cell value rankings-table__value'}).text.strip()
            data['players'].append(players)
            data['club'].append(club)
            data['rank'].append(rank)
        print(data)
    
    getstuff(soup)
    """
    {'players': ['Lionel Messi', 'Junior Neymar', 'Robert Lewandowski', 'Joao Cancelo', 'Kevin de Bruyne', 'Rodri', 'Jesse Lingard', 'Riyad Mahrez', 'Ilkay Gundogan', 'John Stones'], 'club': ['Barcelona', 'Paris Saint-Germain', 'Bayern Munich', 'Manchester City', 'Manchester City', 'Manchester City', 'West Ham United', 'Manchester City', 'Manchester City', 'Manchester City'], 'rank': ['100', '95', '93', '92', '91', '90', '90', '89', '88', '88']}
    """
    

    您必须使用.find_all("a") 来获取有关所有玩家的信息。另外,您只是在data['players'] insted 中添加新玩家,对于添加新玩家和俱乐部,排名相同。

    【讨论】:

    • 如何在所有页面上执行此操作?我已经尝试过,但是输出只像以前一样返回单个玩家,请查看我更新的问题。
    【解决方案2】:

    您正在覆盖每个循环中的变量,而不是附加到数据集。此外,您的产品搜索中只有一位玩家。

    试试

    data = []
    
    
    products = soup.select('a .rankings-table-row')
    for name in products:
        players = name.find('div', {'class':'player-name rankings-table__player-name'}).text
        club = name.find('span', {'class':'rankings-table__club-name'}).text
        rank = name.find('div', {'class':'rankings-table-cell value rankings-table__value'}).text.strip()
    
        data.append(
            {
             'Players':  players,
             'Club': club,
             'Rank': rank
            }            
            )
    data = pd.DataFrame(data)  
              
    

    【讨论】:

    • :a .rankings-table-row 代表什么?如果我理解正确,a 是选择标签,. 表示选择rankings-table-row 内的所有内容?
    • 有几种不同的方法可以从网站中“选择”项目(html 标签、css 选择器、xpath) 我上面使用的一种是 css 选择器。 Reference here 我根据需要和可读性在不同类型之间进行切换。除了内置浏览器“检查”之外,一个超级方便的工具是“SelectorGadget”,它是大多数浏览器上的一个插件,值得一试,它的输出是一个 css 选择器,但也可以提供一个 xpath。
    【解决方案3】:

    你应该试试

    data['players'].append(players)
    

    这是一个列表,所以附加应该可以工作。一个列表只能通过附加来添加,如果你这样做了

    data['players'] = players
    

    它会将“玩家”键分配给一个值。其他键也是如此

    我下面的答案也提到你应该使用'find_all'。

    【讨论】:

    • 这并不能解决 OP 的所有问题。我已经给出了完整的答案。你可以在那里检查。
    • 是的。我还在最后一行引用了您的答案。
    【解决方案4】:

    我也尝试过解决这个问题,但使用的是硒。我什至使用了显式等待:WebDriverWait,以确保元素加载。

    仍然只有梅西回归,其他球员都没有。这些元素作为条目存在,但是当尝试访问它们的“.text”时,它们返回空白。上面的人尝试过他们建议的解决方案吗?

    【讨论】:

    • 没有检查其他人,但我的工作。您是否更改了 products 行以查找所有元素?
    • @Quixotic22 检查了你和另一个人的 .它适用于请求和汤。但是在硒中,我什至找不到我在主页上“检查”的元素。总之,问题解决了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 2019-01-13
    相关资源
    最近更新 更多