使用 BeautifulSoup 提取特定的 dl 和 dd 列表元素
Using BeautifulSoup to extract specific dl and dd list elements
第一次发帖。我正在使用 BeautifulSoup 4 和 python 2.7 (pycharm)。我有一个包含元素的网页,我需要提取标签为 'Salary:' 或 'Date:' 的特定元素,该页面包含多个列表。
问题:我似乎无法识别和提取特定文本。我已经搜索过这个网站,但没有成功。
示例html:
<dl><dt>Date:</dt><dd>13 September 2015</dd><dt>Salary:</dt><dd>Starting at £40,130 per annum.</dd></dl><dl><dt>Date:</dt><dd>15 December 2015</dd><dt>Salary:</dt><dd>Starting at £22,460 per annum.</dd></dl><dl><dt>Date:</dt><dd>10 January 2014</dd><dt>Salary:</dt><dd>Starting at £18,160 per annum.</dd></dl>
我试过没有成功的代码:
r = requests.get("http://www.mywebsite.com/test.html")
soup = BeautifulSoup(r.content, "html.parser")
dl_data = soup.find_all("dl")
for dlitem in dl_data:
print dlitem.find("dt",text="Date:").parent.findNext("dd").contents[0]
print dlitem.find("dt",text="Salary:").parent.findNext("dd").contents[0]
预期结果:
13 September 2015
15 December 2015
10 January 2014
Starting at £40,130 per annum.
Starting at £22,460 per annum.
Starting at £18,160 per annum.
实际结果:
print dlitem.find("dt",text="Date:").parent.findNext("dd").contents[0]
AttributeError: 'NoneType' object has no attribute 'parent'
我尝试了此代码的多种变体并绕了一圈,我想出了如何将所有 dd 元素打印到屏幕上,而不是特定的 dd 元素!
谢谢
如果顺序不重要,只需进行一些更改:
...
dl_data = soup.find_all("dd")
for dlitem in dl_data:
print dlitem.string
结果:
13 September 2015
Starting at £40,130 per annum.
15 December 2015
Starting at £22,460 per annum.
10 January 2014
Starting at £18,160 per annum.
对于您的最新请求:
for item in list(zip(soup.find_all("dd")[0::3],soup.find_all("dd")[2::3])):
date, salary = item
print ', '.join([date.string, salary.string])
输出:
13 September 2015, 100
14 September 2015, 200
我想如果您在代码中省略 .parent
就可以了。至少这对我的问题有效,与你的问题非常相似。
这是我的 html,其中无法保证 <dt>
的顺序:
<dl>
<dt>Time</dt><dd>10:05:02</dd>
<dt>Temp</dt><dd>20.5°C</dd>
</dl>
我正在使用以下代码成功访问这些值:
time = at_tl.find("dt",text="Time").findNext("dd").string
temp = at_tl.find("dt",text="Temp").findNext("dd").string
一个更稳健的解决方案是将 dl 中的所有 (dt,dd) 元素组成 dict
对 (key,value)。然后 select 字典中的所需字段。
如何将 'dl' 元素转换为字典
一些class“obj”中的数据:
html = """
<dl class="obj">
<dt>Time</dt> <dd>10:00</dd>
<dt>Temp</dt> <dd>20.5°C</dd>
</dl>
"""
保存所有的“dt”a和“dl”,然后将它们压缩成字典:
def get_dl(soup):
keys, values = [], []
for dl in soup.findAll("dl", {"class": "obj"}):
for dt in dl.findAll("dt"):
keys.append(dt.text.strip())
for dd in dl.findAll("dd"):
values.append(dd.text.strip())
return dict(zip(keys, values))
soup = BeautifulSoup(html, features="html.parser")
dl_dict = get_dl(soup)
输出:
{'Time': '10:00', 'Temp': '20.5°C'}
第一次发帖。我正在使用 BeautifulSoup 4 和 python 2.7 (pycharm)。我有一个包含元素的网页,我需要提取标签为 'Salary:' 或 'Date:' 的特定元素,该页面包含多个列表。
问题:我似乎无法识别和提取特定文本。我已经搜索过这个网站,但没有成功。
示例html:
<dl><dt>Date:</dt><dd>13 September 2015</dd><dt>Salary:</dt><dd>Starting at £40,130 per annum.</dd></dl><dl><dt>Date:</dt><dd>15 December 2015</dd><dt>Salary:</dt><dd>Starting at £22,460 per annum.</dd></dl><dl><dt>Date:</dt><dd>10 January 2014</dd><dt>Salary:</dt><dd>Starting at £18,160 per annum.</dd></dl>
我试过没有成功的代码:
r = requests.get("http://www.mywebsite.com/test.html")
soup = BeautifulSoup(r.content, "html.parser")
dl_data = soup.find_all("dl")
for dlitem in dl_data:
print dlitem.find("dt",text="Date:").parent.findNext("dd").contents[0]
print dlitem.find("dt",text="Salary:").parent.findNext("dd").contents[0]
预期结果:
13 September 2015
15 December 2015
10 January 2014
Starting at £40,130 per annum.
Starting at £22,460 per annum.
Starting at £18,160 per annum.
实际结果:
print dlitem.find("dt",text="Date:").parent.findNext("dd").contents[0]
AttributeError: 'NoneType' object has no attribute 'parent'
我尝试了此代码的多种变体并绕了一圈,我想出了如何将所有 dd 元素打印到屏幕上,而不是特定的 dd 元素!
谢谢
如果顺序不重要,只需进行一些更改:
...
dl_data = soup.find_all("dd")
for dlitem in dl_data:
print dlitem.string
结果:
13 September 2015
Starting at £40,130 per annum.
15 December 2015
Starting at £22,460 per annum.
10 January 2014
Starting at £18,160 per annum.
对于您的最新请求:
for item in list(zip(soup.find_all("dd")[0::3],soup.find_all("dd")[2::3])):
date, salary = item
print ', '.join([date.string, salary.string])
输出:
13 September 2015, 100
14 September 2015, 200
我想如果您在代码中省略 .parent
就可以了。至少这对我的问题有效,与你的问题非常相似。
这是我的 html,其中无法保证 <dt>
的顺序:
<dl>
<dt>Time</dt><dd>10:05:02</dd>
<dt>Temp</dt><dd>20.5°C</dd>
</dl>
我正在使用以下代码成功访问这些值:
time = at_tl.find("dt",text="Time").findNext("dd").string
temp = at_tl.find("dt",text="Temp").findNext("dd").string
一个更稳健的解决方案是将 dl 中的所有 (dt,dd) 元素组成 dict
对 (key,value)。然后 select 字典中的所需字段。
如何将 'dl' 元素转换为字典
一些class“obj”中的数据:
html = """
<dl class="obj">
<dt>Time</dt> <dd>10:00</dd>
<dt>Temp</dt> <dd>20.5°C</dd>
</dl>
"""
保存所有的“dt”a和“dl”,然后将它们压缩成字典:
def get_dl(soup):
keys, values = [], []
for dl in soup.findAll("dl", {"class": "obj"}):
for dt in dl.findAll("dt"):
keys.append(dt.text.strip())
for dd in dl.findAll("dd"):
values.append(dd.text.strip())
return dict(zip(keys, values))
soup = BeautifulSoup(html, features="html.parser")
dl_dict = get_dl(soup)
输出:
{'Time': '10:00', 'Temp': '20.5°C'}