Python Web Scraping:从 Infobox Geography Vcard 中提取维基百科中的区域面积

Python Web Scraping: Extracting the Area of a Region in Wikipedia from the Infobox Geography Vcard

我知道这类问题已被处理过无数次,但在梳理了几个小时的答案和指南后,我还是无法解决这个问题,非常感谢您的帮助。

理想情况下,我想提取维基百科信息框中列出的以平方公里为单位的区域。例如,我 运行 在 https://en.wikipedia.org/wiki/Sandton 上的代码应该产生类似“143.54 km”的内容。

我使用大量指南放在一起的代码似乎只适用于整个国家/地区的维基百科网站,其中“区域”实际上是 link。在西班牙的维基百科页面上试试这个:

from bs4 import BeautifulSoup
import requests

def getAdditionalDetails(URL):
    try:
        soup = BeautifulSoup(requests.get(URL).text, 'lxml')
        table = soup.find('table', {'class': 'infobox geography vcard'})
        additional_details = []
        read_content = False
        for tr in table.find_all('tr'):
            if (tr.get('class') == ['mergedtoprow'] and not read_content):
                link = tr.find('th')
                if (link.get_text().strip() == 'Area'):
                    read_content = True
                if (link.get_text().strip() == 'Population'):
                    read_content = False
            elif ((tr.get('class') == ['mergedrow'] or tr.get('class') == ['mergedbottomrow']) and read_content):
                additional_details.append(tr.find('td').get_text().strip('\n')) 
                if (tr.find('div').get_text().strip() != '•\xa0Total area'):
                    read_content = False
        return additional_details
    except Exception as error:
        print('Error occured: {}'.format(error))
        return []

URL = "https://en.wikipedia.org/wiki/Spain"
print(getAdditionalDetails(URL))

这输出几乎可用:

['505,990[6]\xa0km2 (195,360\xa0sq\xa0mi) (51st)']

有比我更聪明的人帮忙吗?

谢谢。

这不是最干净的方法,但可以。如果您想要特定的行,请从 CSS 选择器开始。

代码示例

import requests
from bs4 import BeautifulSoup

url = 'https://en.wikipedia.org/wiki/Sandton'
html = requests.get(url)
soup = BeautifulSoup(html.text,'html.parser')

area = soup.select('table > tbody > tr')[9].get_text(strip=True)
area = area.replace('\xa0', '').split('(')[0]
cleaned_area = area[7:]

输出

143.54 km2(55.42 sq mi)

解释

这段代码中的区域变量我们使用 CSS 选择器专门选择行。

get_text(strip=True) 是抓取文本的方法,但它会去除所有白色 space。您应该知道 \xa0 在 Latin1 编码中是不间断的 space 。 Strip=True 将在字符串的开头和结尾删除它。

没有strip=True的区域变量的输出看起来像这样

'\xa0•\xa0Total143.54\xa0km2 (55.42\xa0sq\xa0mi)'

有 strip=True

'•\xa0Total143.54\xa0km2(55.42\xa0sq\xa0mi)'

所以你仍然卡在字符串中。

使用替换字符串的方法,我们可以用 space.

替换 \xa0

所以输出

'• Total143.54 km2(55.42 sq mi)'

然后因为我们实际上不需要前 7 个字符,我们只需要使用字符串附带的切片从第 8 个字符开始。

附加信息

编码在 python 和一般计算中是一个很大的话题,了解一点它很重要。编码本质上是存在的,因为无论喜欢与否,计算机中的一切都是一个字节。必须有从硬件到软件的转换,编码是该步骤的一部分。

我们希望能够将字符转换为位,以便计算机可以在我们编写代码时执行某些操作。

最简单的编码类型是 ASCII,您可能在某些时候已经遇到过。整个ASCII码table有128个字符对应'Code Points'

ASCII码点:97

字符:一个

现在您可能会问这有什么意义?好吧,我们可以将这些字符转换为代码点,这些代码点很容易转换为二进制文件。这很容易转换为位(1 或 0),供计算机在硬件级别执行某些操作。

现在 ASCII 的问题是人类语言中的字符比 128 个字符多得多...所以输入一种新的编码类型。有很多,最常见的是 Unicode,我提供了一些资源来进一步了解它。

现在 Latin-1 编码是 HTTP 请求的默认编码,请求库严格遵循此编码。

部分资源:

The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

Pragmatic Unicode

Real Python | Encoding

What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text