首页 > 解决方案 > 使用 BeautifulSoup 获取 span 中的 span 的文本

问题描述

我正在尝试使用此站点上的 Beautiful Soup 从站点返回 城市国家地区: https ://www.geodatatool.com/en/?ip=82.47.160.231 (别担心这不是我的 IP ; 虚拟IP)

这就是我正在尝试的:

    url = "https://www.geodatatool.com/en/?ip="+ip
    
    # Getting site's data in plain text..
    sourceCode = requests.get(url)
    plainText = sourceCode.text
    soup = BeautifulSoup(plainText)
    
    tags = soup('span')
    # Parsing data.
    data_item = soup.body.findAll('div','data-item')
    
    #bold_item = data_item.findAll('span')
    for tag in tags:
        print(tag.contents)

我只是得到一个包含所有跨度内容的数组。试图将其范围缩小到具体我的需求,但这不会很快发生。

有人可以帮我解决这个问题吗?

标签: web-scrapingbeautifulsoup

解决方案


这应该有效。基本上我们找到所有具有类:'data-item'的div,然后在这里我们正在寻找2个跨度,其中第一个跨度是城市:,国家:等,第二个跨度包含数据。

data_items = soup.findAll('div', {'class': 'data-item'})

# Country
country = data_items[2].findAll('span')[1].text.strip()

# City 
city = data_items[5].findAll('span')[1].text.strip()

# Region
country = data_items[4].findAll('span')[1].text.strip()

一般来说,这是可行的,但如果网站显示不同的数据或每次搜索对数据排序不同,我们可能希望使代码更健壮一些。我们可以通过使用正则表达式来查找国家、城市和地区字段来做到这一点。解决方案如下:

# Country
country = soup.find(text=re.compile('country', re.IGNORECASE)).parent.parent.findAll('span')[1].text.strip()

# City 
city = soup.find(text=re.compile('city', re.IGNORECASE)).parent.parent.findAll('span')[1].text.strip()

# Region
region = soup.find(text=re.compile('region', re.IGNORECASE)).parent.parent.findAll('span')[1].text.strip()

我们尝试在 HTML 代码中找到模式“国家”、“城市”或“地区”。然后抓取它们的父级 2 次以获得与之前代码块中的 data_items 相同的结果,并执行相同的操作以获得答案。


推荐阅读