【问题标题】:Parsing HTML data with lxml使用 lxml 解析 HTML 数据
【发布时间】:2012-01-27 23:38:33
【问题描述】:

我是编码初学者,我的一个朋友告诉我使用 BeautifulSoup 而不是 htmlparser。在遇到一些问题后,我得到了使用 lxml 而不是 BeaytifulSoup 的提示,因为它要好 10 倍。

我希望有人能给我提示如何抓取我要查找的文本。

我想要的是找到一个包含以下行和数据的表:

<tr>
    <td><a href="website1.com">website1</a></td>
    <td>info1</td>
    <td>info2</td>              
    <td><a href="spam1.com">spam1</a></td>
</tr>
<tr>
    <td><a href="website2.com">website2</a></td>
    <td>info1</td>
    <td>info2</td>              
    <td><a href="spam2.com">spam2</a></td>
</tr>

我如何使用lxml 抓取包含信息 1 和 2 的网站,没有垃圾邮件,并获得以下结果?

[['url' 'info1', 'info2'], ['url', 'info1', 'info2']]

【问题讨论】:

    标签: python html-parsing lxml


    【解决方案1】:
    import lxml.html as lh
    
    tree = lh.fromstring(your_html)
    
    result = []
    for row in tree.xpath("tr"):
        url, info1, info2 = row.xpath("td")[:3]
        result.append([url.xpath("a")[0].attrib['href'],
                       info1.text_content(),
                       info2.text_content()])
    

    结果:

    [['website1.com', 'info1', 'info2'], ['website2.com', 'info1', 'info2']]

    【讨论】:

      【解决方案2】:

      我使用 xpathtd/a[not(contains(.,"spam"))]/@href | td[not(a)]/text()

      $ python3
      >>> import lxml.html
      >>> doc = lxml.html.parse('data.xml')
      >>> [[j for j in i.xpath('td/a[not(contains(.,"spam"))]/@href | td[not(a)]/text()')] for i in doc.xpath('//tr')]
      [['website1.com', 'info1', 'info2'], ['website2.com', 'info1', 'info2']]
      

      【讨论】:

      • 表中的所有表行都相同。我正在使用 Python 2.7.2+。在表格行中,我只想要前 3 个结果。所以 [['url(website1)', 'info1', 'info2'], ['url(website2)','info1', 'info2']]。感谢您的回复
      • 我认为可以安全地假设实际内容不会包含垃圾邮件。虽然只有@Trees 才能真正告诉我们数据的哪些方面是一致的。
      • @Acorn 更改为 contains(.,"spam")spam 可以替换为 ad.website.com 等模式。
      【解决方案3】:
      import lxml.html as LH
      
      doc = LH.fromstring(content)
      print([tr.xpath('td[1]/a/@href | td[position()=2 or position()=3]/text()')
             for tr in doc.xpath('//tr')])
      

      长 XPath 的含义如下:

      td[1]                                   find the first <td>  
        /a                                    find the <a>
          /@href                              return its href attribute value
      |                                       or
      td[position()=2 or position()=3]        find the second or third <td>
        /text()                               return its text value
      

      【讨论】:

      • 你用几行代码让我很开心。谢谢你的解释。其实所有的答案都很棒。我正在学习使用 firebug 获取它的 xpath。但是他更容易找到第一个表行并处理其中的数据。再次感谢大家,圣诞快乐 :)
      猜你喜欢
      • 1970-01-01
      • 2011-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      • 2013-12-23
      • 2012-08-23
      • 1970-01-01
      相关资源
      最近更新 更多