【问题标题】:Python regular expression for HTML parsing (BeautifulSoup)用于 HTML 解析的 Python 正则表达式 (BeautifulSoup)
【发布时间】:2010-09-08 11:55:02
【问题描述】:

我想获取 HTML 中隐藏输入字段的值。

<input type="hidden" name="fooId" value="12-3456789-1111111111" />

我想在 Python 中编写一个返回 fooId 值的正则表达式,因为我知道 HTML 中的行遵循格式

<input type="hidden" name="fooId" value="**[id is here]**" />

有人可以提供一个 Python 示例来解析 HTML 中的值吗?

【问题讨论】:

    标签: python regex screen-scraping


    【解决方案1】:

    对于这种特殊情况,BeautifulSoup 比正则表达式更难编写,但它更健壮...我只是贡献了 BeautifulSoup 示例,因为您已经知道要使用哪个正则表达式:-)

    from BeautifulSoup import BeautifulSoup
    
    #Or retrieve it from the web, etc. 
    html_data = open('/yourwebsite/page.html','r').read()
    
    #Create the soup object from the HTML data
    soup = BeautifulSoup(html_data)
    fooId = soup.find('input',name='fooId',type='hidden') #Find the proper tag
    value = fooId.attrs[2][1] #The value of the third attribute of the desired tag 
                              #or index it directly via fooId['value']
    

    【讨论】:

    • 我认为“new”关键字不匹配。
    【解决方案2】:

    我同意 Vinko BeautifulSoup 是要走的路。不过我建议使用 fooId['value']get the attribute 而不是依赖 value 作为第三个属性。

    from BeautifulSoup import BeautifulSoup
    #Or retrieve it from the web, etc.
    html_data = open('/yourwebsite/page.html','r').read()
    #Create the soup object from the HTML data
    soup = BeautifulSoup(html_data)
    fooId = soup.find('input',name='fooId',type='hidden') #Find the proper tag
    value = fooId['value'] #The value attribute
    

    【讨论】:

      【解决方案3】:
      import re
      reg = re.compile('<input type="hidden" name="([^"]*)" value="<id>" />')
      value = reg.search(inputHTML).group(1)
      print 'Value is', value
      

      【讨论】:

        【解决方案4】:

        如果可以避免的话,解析是您真的不想自己动手的领域之一,因为您将在未来数年内追查边缘情况和错误

        我建议使用BeautifulSoup。它享有很高的声誉,并且从文档中看起来很容易使用。

        【讨论】:

        • 我同意一般情况,但是如果您正在使用一次性脚本来解析一两个非常具体的事情,那么正则表达式可以让生活更轻松。显然更脆弱,但如果可维护性不是问题,那么它不是问题。也就是说,BeautifulSoup 很棒。
        • 我喜欢正则表达式,但在这一点上必须同意 Orion。这是杰米·扎温斯基(Jamie Zawinski)的名言之一:“现在你有两个问题”
        【解决方案5】:

        Pyparsing 是 BeautifulSoup 和正则表达式之间的一个很好的过渡步骤。它比正则表达式更健壮,因为它的 HTML 标记解析包含大小写、空格、属性存在/不存在/顺序的变化,但执行这种基本的标记提取比使用 BS 更简单。

        您的示例特别简单,因为您要查找的所有内容都在打开的“输入”标签的属性中。这是一个 pyparsing 示例,显示了您的输入标签的几个变体,这些变体将使正则表达式适合,并且还显示了如果标签在评论中,如何不匹配标签:

        html = """<html><body>
        <input type="hidden" name="fooId" value="**[id is here]**" />
        <blah>
        <input name="fooId" type="hidden" value="**[id is here too]**" />
        <input NAME="fooId" type="hidden" value="**[id is HERE too]**" />
        <INPUT NAME="fooId" type="hidden" value="**[and id is even here TOO]**" />
        <!--
        <input type="hidden" name="fooId" value="**[don't report this id]**" />
        -->
        <foo>
        </body></html>"""
        
        from pyparsing import makeHTMLTags, withAttribute, htmlComment
        
        # use makeHTMLTags to create tag expression - makeHTMLTags returns expressions for
        # opening and closing tags, we're only interested in the opening tag
        inputTag = makeHTMLTags("input")[0]
        
        # only want input tags with special attributes
        inputTag.setParseAction(withAttribute(type="hidden", name="fooId"))
        
        # don't report tags that are commented out
        inputTag.ignore(htmlComment)
        
        # use searchString to skip through the input 
        foundTags = inputTag.searchString(html)
        
        # dump out first result to show all returned tags and attributes
        print foundTags[0].dump()
        print
        
        # print out the value attribute for all matched tags
        for inpTag in foundTags:
            print inpTag.value
        

        打印:

        ['input', ['type', 'hidden'], ['name', 'fooId'], ['value', '**[id is here]**'], True]
        - empty: True
        - name: fooId
        - startInput: ['input', ['type', 'hidden'], ['name', 'fooId'], ['value', '**[id is here]**'], True]
          - empty: True
          - name: fooId
          - type: hidden
          - value: **[id is here]**
        - type: hidden
        - value: **[id is here]**
        
        **[id is here]**
        **[id is here too]**
        **[id is HERE too]**
        **[and id is even here TOO]**
        

        您可以看到,pyparsing 不仅匹配这些不可预测的变化,它还返回一个对象中的数据,以便轻松读取各个标签属性及其值。

        【讨论】:

          【解决方案6】:
          /<input type="hidden" name="fooId" value="([\d-]+)" \/>/
          

          【讨论】:

            【解决方案7】:
            /<input\s+type="hidden"\s+name="([A-Za-z0-9_]+)"\s+value="([A-Za-z0-9_\-]*)"\s*/>/
            
            >>> import re
            >>> s = '<input type="hidden" name="fooId" value="12-3456789-1111111111" />'
            >>> re.match('<input\s+type="hidden"\s+name="([A-Za-z0-9_]+)"\s+value="([A-Za-z0-9_\-]*)"\s*/>', s).groups()
            ('fooId', '12-3456789-1111111111')
            

            【讨论】:

              猜你喜欢
              • 2021-07-20
              • 2016-05-01
              • 2012-09-12
              • 2016-09-23
              • 2014-06-26
              • 1970-01-01
              • 2020-03-14
              • 1970-01-01
              • 2014-05-16
              相关资源
              最近更新 更多