我正在尝试学习一个 YouTube 练习,该练习将从 wiki 页面抓取特定的 html 块https://en.wikipedia.org/wiki/Toy_Story_3,我对信息框中的键值对数据感兴趣从该页面并将其放入我的 jupyter 笔记本中的 python dict 对象中,以供我的 panda 学习。 html部分是类名为“infobox vevent”的表。基本上我循环遍历“”标签并进入“”和“”部分以获取数据。这是来自 youtube 的代码,但如果可能的话,我尝试用其他方式进行列表理解。
r = requests.get("https://en.wikipedia.org/wiki/Toy_Story_3")
soup = bs(r.content)
contents =soup.prettify()
info_box = soup.find(class_="infobox vevent")
info_rows = info_box.find_all("tr")
movie_info = {}
for index, row in enumerate(info_rows):
if index == 0:
movie_info['title'] = row.find("th").get_text()
elif index == 1:
continue
else:
content_key = row.find("th").get_text()
content_value =[row_data.get_text() for row_data in row.find("td").find_all("li")]
movie_info[content_key] = content_value
movie_info`
输出是这样的
`{'title': 'Toy Story 3',
'Directed by': [],
'Screenplay by': [],
'Story by': ['John Lasseter', 'Andrew Stanton', 'Lee Unkrich'],
'Produced by': [],
'Starring': ['Tom Hanks',
'Tim Allen',
'Joan Cusack',
'Don Rickles',
'Wallace Shawn',
'John Ratzenberger',
'Estelle Harris',
'Ned Beatty',
'Michael Keaton',
'Jodi Benson',
'John Morris'],
'Cinematography': ['Jeremy Lasky', 'Kim White'],...}
这是我抓取的html部分,
<table class="infobox vevent">
<tbody>
<tr><th>Toy Story 3</th></tr>
<tr><th>Screenplay by</th><td>Michael Arndt</td></tr>
<tr><th>Story by</th><td>
<style data-mw-deduplicate="TemplateStyles:r1126788409">.mw-parser-output .plainlist ol,.mw-parser-output .plainlist ul{line-height:inherit;list-style:none;margin:0;padding:0}.mw-parser-output .plainlist ol li,.mw-parser-output .plainlist ul li{margin-bottom:0}</style>
<div class="plainlist">
<ul>
<li>John Lasseter</li>
<li>Andrew Stanton</li>
<li>Lee Unkrich</li>
</ul>
</div></td></tr>
<tr><th> Produced by</th><td>Darla K. Anderson</td></tr>
<tr><th>Starring</th><td>
<div class="plainlist">
<ul><li><a href="/wiki/Tom_Hanks" title="Tom Hanks">Tom Hanks</a></li>
<li><a href="/wiki/Tim_Allen" title="Tim Allen">Tim Allen</a></li>
<li><a href="/wiki/Joan_Cusack" title="Joan Cusack">Joan Cusack</a></li>
<li><a href="/wiki/Don_Rickles" title="Don Rickles">Don Rickles</a></li>
<li><a href="/wiki/Wallace_Shawn" title="Wallace Shawn">Wallace Shawn</a></li>
<li><a href="/wiki/John_Ratzenberger" title="John Ratzenberger">John Ratzenberger</a></li>
<li><a href="/wiki/Estelle_Harris" title="Estelle Harris">Estelle Harris</a></li>
<li><a href="/wiki/Ned_Beatty" title="Ned Beatty">Ned Beatty</a></li>
<li><a href="/wiki/Michael_Keaton" title="Michael Keaton">Michael Keaton</a></li>
<li><a href="/wiki/Jodi_Benson" title="Jodi Benson">Jodi Benson</a></li>
<li><a href="/wiki/John_Morris_(American_actor)" title="John Morris (American actor)">John Morris</a></li></ul>
.... more html code here
</Other closing markup>
</table>
如您所见,有空值。只有那些有
<li>
子级的才能返回数据,逻辑错误就在这行代码 content_value =[row_data.get_text() for row_data in row.find("td").find_all("li")]
,它忽略了没有 <td>
子级的 <li>
。需要帮助如何将 else 逻辑与此列表压缩行放在一起。我尝试过content_value =[row_data.get_text() for row_data in row.find("td").find_all("li") else row_data.ge_text()]
。我收到语法错误。
如果列表推导式为空,则需要使用
row.find("td").get_text()
来代替。
您可以通过在列表理解之后放置
or
子句来做到这一点。
在 Python 中,当你这样说时:
x = y or z
评估
y
的值,如果它是“true”,则将该值分配给 x
,否则分配 z
的值。
所以你需要在推导式之后添加一个
or
子句:
content_value = [...] or row.find("td").get_text()