首页 > 解决方案 > Python,BeautifulSoup,re:如何将提取的文本从网络转换为字典?

问题描述

我使用 BeautifulSoup 制作了一个脚本来从网络中提取某些信息。唯一的问题是我不知道如何将结果转换为字典,如果我这样做,代码就会像意大利面条一样。我不确定我编写的这段代码是否可以接受为 Pythonic。最后一项Species应该是二项式命名法,例如“Lycaon pictus”,而“pictus”之后的字符串应该被忽略。需要一些帮助。

脚本

from urllib.request import Request, urlopen
from bs4 import BeautifulSoup
import re

url = "https://www.itis.gov/servlet/SingleRpt/SingleRpt?search_topic=TSN&search_value=183833#null"
page = urlopen(Request(url, headers={'User-Agent': 'Mozilla/5.0'}))
soup = BeautifulSoup(page, 'html.parser')
results = soup.findAll('tr')
for result in results:
    text = result.get_text().strip()
    pattern = r"^(Kingdom|Phylum|Division|Class|Order|Family|Genus|Species)[\w]+"
    if re.match(pattern, text):
        res = text.split('\n', 1)[0].strip()
        print(res)

脚本的输出

KingdomAnimalia
PhylumChordata
ClassMammalia Linnaeus, 1758
OrderCarnivora Bowdich, 1821
FamilyCanidae Fischer, 1817
GenusLycaon Brookes, 1827
SpeciesLycaon pictus (Temminck, 1820) – African hunting dog, African Wild Dog, Painted Hunting Dog

预期结果

{
    'Kingdom': 'Animalia',
    'Phylum': 'Chordata',
    'Class': 'Mammalia',
    'Order': 'Carnivora',
    'Family': 'Canidae',
    'Genus': 'Lycaon',
    'Species': 'Lycaon pictus'
}

标签: pythonregexdictionarybeautifulsoupurllib

解决方案


这里的“结果”有点像

<td align="left" class="body" width="2%"> </td>
<td align="left" class="body" valign="top" width="24%">Kingdom</td>
<td class="datafield" valign="top" width="71%"><a href="SingleRpt?search_topic=TSN&amp;search_value=202423">Animalia</a> 
 – Animal, animaux, animals</td>
<td class="body" width="5%"> </td>

当您在其上使用 .get_text() 时,它会变成

'\xa0KingdomAnimalia\xa0\n – Animal, animaux, animals\n\xa0'

因此,在匹配时,您应该使用旧的“结果”并将列拆分。例如:

if re.match(pattern, text)) :
    pieces = result.findAll('td')

然后使用这些片段来查找您的信息,例如

for p in pieces:
    print(p.get_text())

当然,当您使用字符串并且一开始没有进行映射时,您不能期望它返回字典。因此你应该在开始 for 循环之前做一个,让我们称之为dictionary

if re.match(pattern, text):
    p = result.findAll('td')
    rank = p[1].get_text().strip()
    taxon = p[2].get_text().split('\xa0')[0]
    dictionary[rank] = taxon

这会给你你正在寻找的字典


推荐阅读