【问题标题】:Python and Beautifulsoup issue deleting an empty tag in the soup objectPython 和 Beautifulsoup 问题删除汤对象中的空标签
【发布时间】:2019-01-11 20:41:25
【问题描述】:

SO 的老用户,最近刚刚创建了一个帐户。这是我在这里提出问题的第二次尝试。我对 Python 很陌生,但有编程经验,对网络抓取非常陌生。

问题

我编写了一个函数来下载一系列格式非常相似的 HTML 文件。然后我使用 BeautifulSoup 来解析 HTML 文件并最终将数据加载到 SQL 表中。我正在对我们已经拥有的列/表进行差距分析,以了解有多少不同。我正在尝试读取某个 HTML 标签,在某些情况下,还有一组额外的空标签。我真正想做的是简单地删除这个额外的条目并继续前进。我尝试使用 decompose() 函数并尝试通过索引引用值并执行删除。

<dt class="dlterm"></dt>

当我稍后尝试将列名、数据类型和描述存储为记录时,这会丢弃我的列。我不知道如何删除它并继续解析文件。

我可以让 Python 找到 <dt class="dlterm"></dt> 并尝试了 decompose(),pop() 方法,我什至考虑提出一个偏移量并将一个变量设置为 1,当它找到它然后以某种方式偏移循环迭代的其余代码加 1。

我已经开始工作的一个解决方案是通过打开源文件并替换<dt class="dlterm"></dt> 标记来完全解决这个问题,然后我尝试使用beautifulsoup 阅读此内容。借用老同事的一句话,就是“偷偷摸摸”的出路。它可以工作,但对于一个简单的问题似乎有很多代码。

问题

我认为汤对象是一个列表,但它的行为不是这样?汤对象的专有名词是什么?

Python 代码 sn-p

# Load the cursor/recordset
myrecordset = mycursor.fetchall() 

# Outer loop
    for y in myrecordset:

        myfilepath = "myexample.html" % y[2]
        soup = BeautifulSoup(open(myfilepath),"html.parser")

        PageName = soup.find("h1",{"class":"topictitle1"})

        # print ("PageName: " + PageName.text)
            FieldName = soup.find_all("dt", {"class":"dlterm"})
            FieldDataType = soup.find_all("samp", {"class":"codeph"})
            FieldDesc = soup.find_all("dd", {"class":"ddexpand"})
            # outercounter = -1
            #
            # #Fix the empty value issue early that is offsetting everything
            # for z in FieldName:
            #     outercounter+=1
            #     # FieldName[7].decompose()
            #     if z.text == '': # '<dt class="dlterm"></dt>':
            #         z.decompose()
            #
            #         # FieldName[outercounter-1].pop()
    
    
    
            # How to get get the description cleaned up
            # FieldDesc[2].text.replace('\n','').replace('      ', ' ')
            # print(FieldName.text)
            # print(FieldDataType.text)
            # print(FieldDesc.text)
    
            # inner loop
            innercounter1 = 0
            # zip allows me to iterate through multiple lists at the same time
            for (fn, fdt, fd) in zip(FieldName, FieldDataType, FieldDesc):
    
                fntemp= ''
                fdttemp= ''
                fdtemp= ''
    
                fntemp = fn.text
                fdttemp = fdt.text
    
                # clean the string
                if fd.text.__contains__('One of:'):
                    # hold onto the double return while I replace the others.
                    fdtemp = fd.text.replace('\n\n', '<<nn>>')
                    fdtemp = fdtemp.replace('\n',', ')
                    fdtemp = fdtemp.replace('<<nn>>', '\n')
                else:
                    fdtemp = fd.text.replace('\n', ' ')
    
                fdtemp = fdtemp.strip()
    
                # remove all redundant spaces from the string
                fdtemp = " ".join(fdtemp.split())
                # have to escape single quotes in text so it will insert correctly
                fdtemp = fdtemp.replace("'", "''")

                #Insert into SQL

                # ... code continued

显示问题的 HTML 文件片段

<div class="section">
<h2 class="sectiontitle">Title</h2>
<dl>
<dt class="dlterm">Term1</dt><dd><samp class="codeph">nonNegativeInteger</samp></dd><dd class="ddexpand">Blah blah blah about term1</dd>
<dt class="dlterm">Term2</dt><dd><samp class="codeph">nonNegativeInteger</samp></dd><dd class="ddexpand">Blah blah blah about term2</dd>
<dt class="dlterm"></dt><dt class="dlterm">Term3</dt><dd><samp class="codeph">nonNegativeInteger</samp></dd><dd class="ddexpand">Blah blah about term3</dd>
</dl></div>

如果有人能帮我解决这个问题,那就太棒了。

【问题讨论】:

    标签: python web-scraping beautifulsoup


    【解决方案1】:

    decompose() 足以解决您的问题。

    from bs4 import BeautifulSoup
    html="""
    <div class="section">
    <h2 class="sectiontitle">Title</h2>
    <dl>
    <dt class="dlterm">Term1</dt><dd><samp class="codeph">nonNegativeInteger</samp></dd><dd class="ddexpand">Blah blah blah about term1</dd>
    <dt class="dlterm">Term2</dt><dd><samp class="codeph">nonNegativeInteger</samp></dd><dd class="ddexpand">Blah blah blah about term2</dd>
    <dt class="dlterm"></dt><dt class="dlterm">Term3</dt><dd><samp class="codeph">nonNegativeInteger</samp></dd><dd class="ddexpand">Blah blah about term3</dd>
    </dl></div>
    """
    soup=BeautifulSoup(html,'html.parser')
    for tag in soup.find_all('dt',attrs={"class":"dlterm"}): #all dl tags with class dlterm
        if not tag.text: #if tag is empty
            tag.decompose()
    print(soup)
    

    输出

    <div class="section">
    <h2 class="sectiontitle">Title</h2>
    <dl>
    <dt class="dlterm">Term1</dt><dd><samp class="codeph">nonNegativeInteger</samp></dd><dd class="ddexpand">Blah blah blah about term1</dd>
    <dt class="dlterm">Term2</dt><dd><samp class="codeph">nonNegativeInteger</samp></dd><dd class="ddexpand">Blah blah blah about term2</dd>
    <dt class="dlterm">Term3</dt><dd><samp class="codeph">nonNegativeInteger</samp></dd><dd class="ddexpand">Blah blah about term3</dd>
    </dl></div>
    

    【讨论】:

    • 在这里感谢您的帮助。我正在使用 PyCharm,似乎调试器在单步执行时没有向我显示正确的变量值。奇怪的是,如果我像上面在我的代码中所做的那样简单地查看之前和之后的汤变量,那么错误标签现在就消失了。所以现在我不再把我的专栏往下移了。我稍后使用 zip 同时遍历三个类似的变量。这抵消了价值并从那一点向下搞砸了。现在我有一个新问题要解决,但我没有被卡住。
    猜你喜欢
    • 2014-04-25
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多