【问题标题】:Using BeautifulSoup to extract specific dl and dd list elements使用 BeautifulSoup 提取特定的 dl 和 dd 列表元素
【发布时间】:2015-12-05 04:41:18
【问题描述】:

我第一次发帖。我正在使用 BeautifulSoup 4 和 python 2.7 (pycharm)。我有一个包含元素的网页,我需要提取标签为“薪水:”或“日期:”的特定元素,该页面包含多个列表。

问题:我似乎无法识别和提取特定文本。我已经搜索过这个网站并尝试过但没有成功。

示例 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 元素!

谢谢

【问题讨论】:

    标签: python html beautifulsoup extract


    【解决方案1】:

    如果顺序不重要,只需进行一些更改:

    ...
    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
    

    【讨论】:

    • 谢谢你的回答,但是你知道如何通过字符串来识别 Salary: Date: 我上面给出的例子很简单,一些例子我包含了我不需要的其他代码,所以你的例子会提取所有 dd,我需要特定的 dd 文本提取。谢谢
    • BeautifulSoup 能够获取大量信息。请为您的示例提供数据输入和数据输出(正是您希望获得的数据)
    • 请求的另一个示例
      日期:
      2015 年 9 月 13 日
      职位:
      程序员
      薪水:
      100
      日期:
      2015 年 9 月 14 日
      职位:
      数据库Admin
      Salary:
      200
      在这个例子中我只想要日期和薪水信息而不是职位信息,所以我的预期输出是“ 2015 年 9 月 13 日","100","2015 年 9 月 14 日","200" 文本“数据库管理员”和“程序员”将不会显示。谢谢
    【解决方案2】:

    我想如果您在代码中省略.parent,它会起作用。至少这适用于我的问题,这与您的问题非常相似。

    这是我的 html,其中 &lt;dt&gt; 的顺序无法保证:

    <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
    

    【讨论】:

      【解决方案3】:

      更强大的解决方案是在 dl 中为所有 (dt,dd) 元素的 (key,value) 对创建 dict。然后从字典中选择所需的字段。


      如何将 'dl' 元素转换为 dict

      某个类“obj”中的数据:

      html = """
          <dl class="obj">
            <dt>Time</dt> <dd>10:00</dd>
            <dt>Temp</dt> <dd>20.5°C</dd>
          </dl>  
             """
      

      保存所有的“dt”和“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'}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多