【问题标题】:Removing <wbr> tags and grabbing the info between删除 <wbr> 标记并获取之间的信息
【发布时间】:2015-09-25 09:26:21
【问题描述】:

我正在从网页中抓取数据,并且已针对具有&lt;br&gt; 标签的某个部分执行此操作。

<div class="scrollWrapper">
    <h3>Smiles</h3>
    CC=O<br>
    <button type="button" id="downloadSmiles">Download</button>
</div>

我通过执行以下脚本输出CC=O 解决了这个问题。

from lxml import html

page = requests.get('http://chem.sis.nlm.nih.gov/chemidplus/name/'+ substance)
tree = html.fromstring(page.text)
if ("Smiles" in page.text):
        smiles = tree.xpath('normalize-space(//*[text()="Smiles"]/..//br[1]/preceding-sibling::text()[1])')
else:
        smiles = ""

但是,当我浏览其他不同化学品的页面时,我遇到了一些带有标签的页面。我不知道如何在获取它们之间的信息时摆脱它们。下面显示了一个示例,我想要的输出是c1(c2ccccc2)ccc(N)cc1

<div class="scrollWrapper">
   <h3>Smiles</h3>
   c1(c2ccccc2)<wbr>ccc(N)<wbr>cc1<br>
   <button type="button" id="downloadSmiles">Download</button>
</div>

【问题讨论】:

    标签: python lxml wbr


    【解决方案1】:

    &lt;wbr&gt;

    (分词机会)标签指定可以在文本中添加换行符的位置。提示:当一个单词太长,或者你担心浏览器会在错误的地方断行,你可以使用元素来添加断词机会。

    我使用BeautifulSoup 来解析这些数据。

    from bs4 import BeautifulSoup as bs
    
    html = """
    <div class="scrollWrapper">
       <h3>Smiles</h3>
       c1(c2ccccc2)<wbr>ccc(N)<wbr>cc1<br>
       <button type="button" id="downloadSmiles">Download</button>
    </div>
    """
    
    soup = bs(html, "html.parser")
    rows = soup.get_text().split()
    print(rows[1])
    

    输出:

       c1(c2ccccc2)ccc(N)cc1
    

    【讨论】:

    • 好点子和答案,但请注意,他想要的输出是c1(c2ccccc2)ccc(N)cc1,而不是其他两个词。
    • 我正在尝试不使用 BeautifulSoup,因为我现在只想坚持使用 lxml,但如果我无法解决它,我会试一试汤。
    • 已修复。请看一下。 @J.C.Rocamonde
    • 不是偏见,BeautifulSoup 要简单得多。 :) @TimTom
    • 是的,现在好多了。我不知道 BeautifulSoup。似乎很有希望,我想我会试一试,正如@TimTom 所说。
    【解决方案2】:

    最简单的做法是将page.text 中的&lt;wbr&gt; 字符串替换为空字符串,然后再将其解析为html。因为它在&lt;&gt; 内,所以我怀疑您正在寻找的任何有用信息是否会包含它。

    例子-

    from lxml import html
    
    page = requests.get('http://chem.sis.nlm.nih.gov/chemidplus/name/'+ substance)
    tree = html.fromstring(page.text.replace('<wbr>',''))
    if ("Smiles" in page.text):
            smiles = tree.xpath('normalize-space(//*[text()="Smiles"]/..//br[1]/preceding-sibling::text()[1])')
    else:
            smiles = ""
    

    否则你可以使用@Bun 的使用BeautifulSoup 的解决方案,或者编写复杂的xpath。

    此外,对于您的情况,更简单的 xpath 应该是 -

    'normalize-space(//*[text()="Smiles"]/following-sibling::text()[1])'
    

    而不是找出 Smiles 元素,然后获取它的父元素,然后找出第一个 br 元素,它是它的后代,然后获取它的前一个兄弟元素,然后是它的文本。

    您应该直接为 Smiles 元素获取以下同级元素,然后是其文本。

    【讨论】:

    • 很有趣,但是太复杂了。
    • 对不起,它有多复杂?他已经有了在&lt;br&gt;标签之前读取文本的xpath和工作代码,他只需要添加代码来用空字符串替换&lt;wbr&gt;,第二种类型的html页面应该会给他他想要的结果,对吧?
    • 我的意思是,不是程序本身,而是为了清楚起见,@Bun 的答案比使用这个更容易:'normalize-space(//*[text()="Smiles"]/following-sibling::text()[1])'
    • 是的,没错,这只是一个建议,实际答案是替换部分(对他的 OP 自己的 xpath 的建议,以防他不想走 BeautifulSoup 路线)。
    • 谢谢!我听从了你的建议,并以一种奇怪的方式做到了,但它确实有效。 if ("Smiles" in page.text): if ('' in page.text): tree = html.fromstring(page.text.replace('','')) 微笑 = tree. xpath('normalize-space(//*[text()="Smiles"]/following-sibling::text()[1])') else: smiles = tree.xpath('normalize-space(//* [text()="Smiles"]/following-sibling::text()[1])') 其他:smiles = ""
    【解决方案3】:

    只是指出:您可以通过以下方式摆脱特定字符串:

    str.replace(old, "")
    

    例如:

    "c1(c2ccccc2)<wbr>ccc(N)<wbr>cc1<br>".replace("<wbr>", "").replace("<br>", "")
    

    但是,其他答案更接近预期的结果。

    【讨论】:

    • 我可以做一个像if("&lt;wbr&gt;" in page.text) smiles = tree.xpath('normalize-space(//*[text()="Smiles"]/..//wbr[1]/preceding-sibling::text()[1])').replace("wbr&gt;", "").replace("&lt;br&gt;", "")这样的逻辑语句吗?
    • 是的,但是如果没有遇到符合条件的文本,替换方法不会失败,它只是简单地返回相同的字符串。然而,这只是一个简单的建议。最好看看其他答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 2012-05-08
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多