我使用BeautifulSoup编写了一个脚本,用于从web中提取特定信息。唯一的问题是我不知道如何将结果转换成字典,如果我这样做了,代码就会像意大利面一样。我不确定我写的这段代码是否是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'
}
发布于 2018-05-31 18:25:54
对于给定的特定示例,这是可行的:
...
results = soup.findAll('tr')
my_dict = {}
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()
pieces = re.findall(r'[A-Z][ a-z]*', res)
my_dict[pieces[0]] = pieces[1]
print(my_dict)
输出:
{'Kingdom': 'Animalia', 'Phylum': 'Chordata', 'Class': 'Mammalia',
'Order': 'Carnivora', 'Family': 'Canidae', 'Genus': 'Lycaon',
'Species': 'Lycaon pictus'}
这在很大程度上依赖于上面示例中给出的确切格式。例如,如果网站的'Lycaon Pictus'
带有'Species'
的大写'P'
,那么字典中相应的条目将只是'Lycaon'
而不是'Lycaon Pictus'
。
发布于 2018-05-31 18:04:45
这里的"result“类似于
<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&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-loop之前创建一个,让我们将其称为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
这会给你找到你要找的字典
https://stackoverflow.com/questions/50621172
复制相似问题