【发布时间】:2017-01-11 19:54:47
【问题描述】:
(根据收到的反馈对问题进行了编辑。我将根据收到的输入继续对其进行编辑,直到问题得到解决)
我正在学习 Pyhton 和特别是美丽的汤,我正在使用一组包含不同年份流行婴儿名字的 html 文件(例如 baby1990.html 等)在正则表达式上进行 Google 练习。如果您有兴趣,可以在这里找到这个数据集:https://developers.google.com/edu/python/exercises/baby-names
每个 html 文件都包含一个表格,其中包含如下所示的婴儿姓名数据:
在带有婴儿名字的表格之前还有另一张表格。两个表的Tags中的html代码分别如下
<table width="100%" border="0" cellspacing="0" cellpadding="4"> # Unwanted table
<table width="100%" border="0" cellspacing="0" cellpadding="4" summary="formatting"> # targeted table
您可能会观察到目标与不需要的表的属性不同:summary="formatting"
第一个表格——我们必须跳过的那个——有以下 html 代码:
<table width="100%" border="0" cellspacing="0" cellpadding="4">
<tbody>
<tr><td class="sstop" valign="bottom" align="left" width="25%">
Social Security Online
</td><td valign="bottom" class="titletext">
<!-- sitetitle -->Popular Baby Names
</td>
</tr>
<tr bgcolor="#333366"><td colspan="2" height="2"></td></tr>
<tr><td class="graystars" width="25%" valign="top">
<a href="../OACT/babynames/">Popular Baby Names</a></td><td valign="top">
<a href="http://www.ssa.gov/"><img src="/templateimages/tinylogo.gif"
width="52" height="47" align="left"
alt="SSA logo: link to Social Security home page" border="0"></a><a name="content"></a>
<h1>Popular Names by Birth Year</h1>September 12, 2007</td>
</tr>
<tr bgcolor="#333366"><td colspan="2" height="1"></td></tr>
</tbody></table>
在目标表中,代码如下:
<table width="100%" border="0" cellspacing="0" cellpadding="4" summary="formatting">
<tr valign="top"><td width="25%" class="greycell">
<a href="../OACT/babynames/background.html">Background information</a>
<p><br />
Select another <label for="yob">year of birth</label>?<br />
<form method="post" action="/cgi-bin/popularnames.cgi">
<input type="text" name="year" id="yob" size="4" value="1990">
<input type="hidden" name="top" value="1000">
<input type="hidden" name="number" value="">
<input type="submit" value=" Go "></form>
</td><td>
<h3 align="center">Popularity in 1990</h3>
<p align="center">
<table width="48%" border="1" bordercolor="#aaabbb"
cellpadding="2" cellspacing="0" summary="Popularity for top 1000">
<tr align="center" valign="bottom">
<th scope="col" width="12%" bgcolor="#efefef">Rank</th>
<th scope="col" width="41%" bgcolor="#99ccff">Male name</th>
<th scope="col" bgcolor="pink" width="41%">Female name</th></tr>
<tr align="right"><td>1</td><td>Michael</td><td>Jessica</td> # Targeted row
<tr align="right"><td>2</td><td>Christopher</td><td>Ashley</td> # Targeted row
etc...
您可以看到目标行的独特属性是:align = "right"。
现在提取目标单元格内容的代码如下:
with open("C:/Users/ALEX/MyFiles/JUPYTER NOTEBOOKS/google-python-exercises/babynames/baby1990.html","r") \
as f: soup = bs(f.read(), 'html.parser')
print soup.tr
print "number of elemenents in the soup:" , len(soup)
right_table = soup.find("table", summary = "formatting")
print(right_table.prettify())
print "right_table" , len(right_table)
print(right_table[0].prettify())
for row in right_table[1].find_all("tr", allign = "right"):
cells = row.find_all("td")
try:
print "cells[0]: " , cells[0]
except:
print "cells[0] : NaN"
try:
print "cells[1]: " , cells[1]
except:
print "cells[1] : NaN"
try:
print "cells[2]: " , cells[2]
except:
print "cells[2] : NaN"
输出是一条错误消息:
<tr><td align="left" class="sstop" valign="bottom" width="25%">
Social Security Online
</td><td class="titletext" valign="bottom">
<!-- sitetitle -->Popular Baby Names
</td>
</tr>
number of elemenents in the soup: 4
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-116-3ec77a65b5ad> in <module>()
6 right_table = soup.find("table", summary = "formatting")
7
----> 8 print(right_table.prettify())
9
10 print "right_table" , len(right_table)
C:\users\alex\Anaconda2\lib\site-packages\bs4\element.pyc in prettify(self, encoding, formatter)
1198 def prettify(self, encoding=None, formatter="minimal"):
1199 if encoding is None:
-> 1200 return self.decode(True, formatter=formatter)
1201 else:
1202 return self.encode(encoding, True, formatter=formatter)
C:\users\alex\Anaconda2\lib\site-packages\bs4\element.pyc in decode(self, indent_level, eventual_encoding, formatter)
1164 indent_contents = None
1165 contents = self.decode_contents(
-> 1166 indent_contents, eventual_encoding, formatter)
1167
1168 if self.hidden:
C:\users\alex\Anaconda2\lib\site-packages\bs4\element.pyc in decode_contents(self, indent_level, eventual_encoding, formatter)
1233 elif isinstance(c, Tag):
1234 s.append(c.decode(indent_level, eventual_encoding,
-> 1235 formatter))
1236 if text and indent_level and not self.name == 'pre':
1237 text = text.strip()
... last 2 frames repeated, from the frame below ...
C:\users\alex\Anaconda2\lib\site-packages\bs4\element.pyc in decode(self, indent_level, eventual_encoding, formatter)
1164 indent_contents = None
1165 contents = self.decode_contents(
-> 1166 indent_contents, eventual_encoding, formatter)
1167
1168 if self.hidden:
RuntimeError: maximum recursion depth exceeded while calling a Python object
问题如下:
既然我们已经传递了参数 summary = "formatting",为什么代码会返回第一个表——不需要的表?
错误消息意味着什么?为什么要创建它?
您可以在代码中观察到哪些其他错误 - 如果有的话?
您的建议将不胜感激。
【问题讨论】:
-
如果不得不猜测,我会说
soup.find没有发现任何事件,因此它返回了None。这就是为什么您在尝试获取长度时遇到错误的原因。再次查看该函数的参数和您正在使用的文件,看看为什么它没有找到任何东西。 -
关于文本,随机的空格和缩进让它看起来很乱。最后一部分可能以列表理解的形式组合在一起,而不是三个不同的
TryExcept。也不要简单地使用Except,它可能会忽略一些您不想要的异常。如果您无法更准确地了解预期的异常,请使用Except exception as e并在该块中使用 `print(e)´ -
@Zanzag 感谢您写下您的意见。当您说文本混乱时,我不太明白您的意思。我已经发布了 html 代码和代码,以便您可以检查它们并诊断问题而不是猜测。
标签: python html beautifulsoup