【问题标题】:How can I only extract HTML tags that have <p> with <strong> inside?如何仅提取具有 <p> 和 <strong> 的 HTML 标记?
【发布时间】:2014-07-04 10:06:08
【问题描述】:

我正在使用 Beautiful Soup 进行一些网页抓取。我已将输出范围缩小到以下范围:

[<p><a class="puCloselink" href="javascript:window.close();" id="ctl00_CloseThisPage" onclick="javascript:window.close();" title="Close Window" usesubmitbehavior="false">Close Window</a></p>, <p class="txtBoxAlign">
<span style="display:none"><input id="Location" name="Location" type="hidden"     value="48001"/>
</span>
<input id="newLocation" type="text"/>
<input id="GeoCode" name="GeoCode" type="hidden" value=""/>
<label for="newLocation">Address or ZIP Code (Required): </label>
</p>, <p class="PharmacyNameTxtBox txtBoxAlign">
<input id="PharmacyName" name="PharmacyName" type="text" value=""/>
<label for="PharmacyName">Pharmacy Name: </label>
</p>, <p>
<strong>CVS Pharmacy #</strong><br/>
                        1025 St Clair River Dr <br/>
                        Algonac, MI 48001<br/>
                        1-810-794-4941
                        </p>, <p>
                     Retail
                       </p>, <p>
                        Not applicable
                        </p>, <p>
<strong>Kroger Pharmacy</strong><br/>
                        2600 Pointe Tremble <br/>
                        Algonac, MI 48001<br/>
                        1-810-671-4002
                        </p>, <p>
                     Retail
                       </p>, <p>
                        Not applicable
                        </p>, <p>
<strong>Rite Aid Pharmacy 04943</strong><br/>
                        402 Pointe Tremble Road <br/>
                        Algonac, MI 48001<br/>
                        1-810-794-4985
                        </p>, <p>
                     Retail
                       </p>, <p>
                        Not applicable
                        </p>]

如您所见,有一些“p”标签内部带有“strong”,而一些“p”标签内部没有“string”。如何隔离整个“p”标签,但只针对那些包含“strong”的“p”?

谢谢。

【问题讨论】:

    标签: python html web-scraping beautifulsoup


    【解决方案1】:

    使用ElementTree 解析和隔离所需的文本。不要忘记在您的 html 周围放置一个行标签,以赋予它一个根并使其可解析。

    import xml.etree.ElementTree as ElementTree
    
    myHTML = '<row> <p><a class="puCloselink" href="javascript:window.close();" id="ctl00_CloseThisPage" onclick="javascript:window.close();" title="Close Window" usesubmitbehavior="false">Close Window</a></p>, <p class="txtBoxAlign"> <span style="display:none"><input id="Location" name="Location" type="hidden"     value="48001"/> </span> <input id="newLocation" type="text"/> <input id="GeoCode" name="GeoCode" type="hidden" value=""/> <label for="newLocation">Address or ZIP Code (Required): </label> </p>, <p class="PharmacyNameTxtBox txtBoxAlign"> <input id="PharmacyName" name="PharmacyName" type="text" value=""/> <label for="PharmacyName">Pharmacy Name: </label> </p>, <p> <strong>CVS Pharmacy #</strong><br/> 1025 St Clair River Dr <br/> Algonac, MI 48001<br/> 1-810-794-4941 </p>, <p> Retail </p>, <p> Not applicable </p>, <p> <strong>Kroger Pharmacy</strong><br/> 2600 Pointe Tremble <br/> Algonac, MI 48001<br/> 1-810-671-4002 </p>, <p> Retail </p>, <p> Not applicable </p>, <p> <strong>Rite Aid Pharmacy 04943</strong><br/> 402 Pointe Tremble Road <br/> Algonac, MI 48001<br/> 1-810-794-4985 </p>, <p> Retail </p>, <p> Not applicable </p> </row>'
    
    root = ElementTree.fromstring(myHTML)
    
    p_elements = root.findall("p")
    
    p_strong_elements = []
    
    for element in p_elements:
       if element.find('strong') is not None:
          p_strong_elements.append(element)
    
    # Borrowed from this post: http://stackoverflow.com/questions/380603/how-do-i-get-the-whole-text-of-an-element-using-elementtree
    for p_strong_element in p_strong_elements:
        print "<"+p_strong_element.tag+"> "+"".join( [ p_strong_element.text ] + [ ElementTree.tostring(e) for e in p_strong_element.getchildren() ] )+"</"+p_strong_element.tag+"> "
    >>>'<p>  <strong>CVS Pharmacy #</strong><br /> 1025 St Clair River Dr <br /> Algonac, MI 48001<br /> 1-810-794-4941 </p> '
    >>>'<p>  <strong>Kroger Pharmacy</strong><br /> 2600 Pointe Tremble <br /> Algonac, MI 48001<br /> 1-810-671-4002 </p> '
    >>>'<p>  <strong>Rite Aid Pharmacy 04943</strong><br /> 402 Pointe Tremble Road <br /> Algonac, MI 48001<br /> 1-810-794-4985 </p> 
    

    '

    【讨论】:

    • -1 这并不是 OP 所要求的。在这里你提取&lt;p&gt; 的所有&lt;strong&gt; 孩子,他想提取至少一个&lt;strong&gt; 孩子的&lt;p&gt;。这就是你可以用 jQuery 编写的内容,例如 p:has(strong)。在这里我会使用for tag in root.find_all("p/strong") print tag.parent。注意.parent 属性。
    • 哦顺便说一句,即使.parent 也不是很好,因为它会包含重复项(如果一个&lt;p&gt; 包含多个&lt;strong&gt;)。原始解决方案可能是每个find_all("p") 上的find("strong"),如果它返回None,则跳过(无论如何性能应该不会那么好)。
    • 就像阿德里亚诺所说,我不想提取“p”的“字符串”部分,我只想将结果缩小到所有包含“强”HTML标签的“p”
    • @user2395969 是的,数组“p_strong_elements”仅由那些包含“strong”标签的“p”元素对象组成。所以只需对这些进行操作。字符串/打印语句仅用于说明目的。
    • 对不起,当我运行你的代码时,我得到:>>>CVS Pharmacy # >>>Kroger Pharmacy >>>Rite Aid Pharmacy 04943 当我想要的是完整的“p”包括“strong”以及“strong”标签后的地址和电话号码。
    【解决方案2】:

    找到了一个非常简单的答案:

    for i in table:
        if "strong" in str(i):
            address.append(i)
    

    可能不是最优雅的方式,但它对我有用。

    【讨论】:

      猜你喜欢
      • 2020-09-12
      • 2020-09-09
      • 1970-01-01
      • 2012-10-27
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多