【问题标题】:Parsing all input tags of a page解析页面的所有输入标签
【发布时间】:2017-05-22 09:11:32
【问题描述】:

我正在尝试解析页面中 (type = text) 的所有输入标签:http://demo.testfire.net/feedback.aspx

正如您在上面的网址中看到的,有两种形式。

import bs4 as bs 
import urllib.request
import requests
import webbrowser
import urllib.parse

url = "http://demo.testfire.net/feedback.aspx"

sauce = urllib.request.urlopen(url).read()
soup = bs.BeautifulSoup(sauce,"html.parser")

form = soup.find('form')
inputs = form.find('input', type='text').get('name')
print(inputs)

当我运行上面的代码时,我只得到第一个表单的 name 属性。即使我使用以下内容进行迭代:

for elements in inputs:
   print(elements.get('name'))

我只得到第一种形式的名称属性。无论编号如何,如何解析任何页面的所有表单和所有输入。页面中的表单数量?

如果我使用 soup.find_all('form') 而不是 find(form) 我会收到错误消息。上面的代码有什么问题?

【问题讨论】:

    标签: python beautifulsoup


    【解决方案1】:

    您可以使用这样的代码从页面中获取所有 input 元素。

    >>> import requests
    >>> from bs4 import BeautifulSoup
    >>> url = 'http://demo.testfire.net/feedback.aspx'
    >>> page = requests.get(url).text
    >>> soup = BeautifulSoup(page, 'lxml')
    >>> inputs = soup.findAll('input', attrs={'type': 'text'})
    >>> len(inputs)
    3
    >>> for input in inputs:
    ...     input.attrs['name']
    ... 
    'txtSearch'
    'name'
    'email_addr'
    

    但是,我希望您希望所有input 元素都能够接收表单内的字符串输入,无论它们是否已正确标记为类型。这部分代码非常不一致(例如,并非所有input 元素都有type),在我看来,可能有必要解析出表格的行,然后从中进行选择。

    >>> form = soup.find('form', attrs={'name': 'cmt'})
    >>> table = form.find('table')
    >>> leftColumns = table.findAll('td', attrs={'align': 'right'})
    >>> for column in leftColumns[1:-1]:
    ...     column.findNextSibling().findChild()
    ... 
    <input name="name" size="25" type="text" value=" "/>
    <input name="email_addr" size="25" type="text"/>
    <input name="subject" size="25"/>
    

    etree 的使用可能更容易,因为您可以使用 xpath 表达式。在这种情况下,我注意到所需的 input 元素都具有非空的 size 属性。

    >>> from lxml import etree
    >>> parser = etree.HTMLParser()
    >>> tree = etree.fromstring(page, parser=parser)
    >>> inputs = tree.xpath('.//form[@name="cmt"]//input[@size and string-length(@size)]')
    >>> len(inputs)
    3
    >>> for input in inputs:
    ...     input.attrib
    ...     
    {'value': ' ', 'name': 'name', 'size': '25', 'type': 'text'}
    {'name': 'email_addr', 'size': '25', 'type': 'text'}
    {'name': 'subject', 'size': '25'}
    

    【讨论】:

      【解决方案2】:

      将您的代码更改为:

      import bs4 as bs 
      import urllib.request
      import requests
      import webbrowser
      import urllib.parse
      
      url = "http://demo.testfire.net/feedback.aspx"
      
      sauce = urllib.request.urlopen(url).read()
      soup = bs.BeautifulSoup(sauce,"html.parser")
      
      form = soup.findAll('form')
      for i in form:
         inputs = i.find('input').get('name')
         print(inputs)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-08-26
        • 1970-01-01
        • 1970-01-01
        • 2014-08-02
        • 1970-01-01
        • 1970-01-01
        • 2012-08-19
        相关资源
        最近更新 更多