【问题标题】:Excluding all tables with XPath and Scrapy使用 XPath 和 Scrapy 排除所有表
【发布时间】:2017-04-30 08:56:25
【问题描述】:

我有以下html:

<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8">
      <title>Scrapy</title>
   </head>
   <body>
      <table style="border: #ffffff 0px solid" cellpadding="0" cellspacing="0" width="100%">
         <tr>
            <td align="center">
               <div style="margin-top:7px;margin-bottom:7px;font-size:16px;font-weight:bold;font-color:white" width="100%">
                  Scrapy Rocks
               </div>
            </td>
         </tr>
      </table>
      <table cellpadding="0" cellspacing="0" width="100%" style="margin-top:25px">
         <tr>
            <td align="left" valign="top"></td>
            <td valign="top">
               <font size="-1">
                  <div style="margin-right:10; margin-top:5; text-align: right">
                     <a href="/aaa.html" target="_top">AAA</a> | 
                     <a href="/bbb.html" target="_top">BBB</a> | 
                     <a href="/ccc.html" target="_top">CCC</a>
                  </div>
               </font>
            </td>
         </tr>
         <tr>
            <td align="left" valign="top">
               <div>
                  <a href="http://example.com" target="_blank">
                    <img src="/images/a.jpg" border="0" vspace="0" width="100" height="100" valign="middle"/>
                  </a>
                  <a href="/index.html">
                    <img src="/images/aaa.gif" border="0" vspace="0" width="100" height="100" valign="middle"/>
                  </a>
               </div>
            </td>
            <td valign="top">
               <div style="margin-right:10; margin-top:5; text-align: right"></div>
            </td>
         </tr>
      </table>
      <hr size=1>
      <h2 style="margin-top: 36px; margin-bottom: 24px">
         Abcd efgh for 2017
      </h2>
      Part 1 | 
      Part 2 | 
      Part 3 | 
      Part 4 | 
      <a href="#">A very bold title</a>
      <hr size="1" style="margin-top: 36px; margin-bottom: 24px">
      <a name="part1"></a>
      <h3>Part 1</h3>
      <ul>
      </ul>
      <a name="part2"></a>
      <h3>Part 2</h3>
      <ul>
      </ul>
      <a name="part3"></a>
      <h3>Part 3</h3>
      <ul>
      </ul>
      <a name="part4"></a>
      <h3>Part 4</h3>
      <ul>
      </ul>
      <div style="margin-top: 36px; margin-bottom: 24px">
         <a name="non_rep"></a>
         <h3>Abcd efgh</h3>
      </div>
      <b>January 2017</b>
      <ul>
         <li>
            <b>Part1 1</b>
         </li>
         <ul>
            <li>
               <a href="/cgi-bin/o.pl?file=/a/1.htm">Title 1</a>
            </li>
            <br>
            <li>
               <a href="/cgi-bin/o.pl?file=/a/11.htm">Title 2</a>
            </li>
            <br>
         </ul>
         <li>
            <b>Part1 2</b>
         </li>
         <ul>
            <li>
               <a href="/cgi-bin/o.pl?file=/a/2.htm">Title A</a>
            </li>
            <br>
            <li>
               <a href="/cgi-bin/o.pl?file=/a/22.htm">Title B</a>
            </li>
            <br>
         </ul>
         <li>
            <b>Part1 3</b>
         </li>
         <ul>
            <li>
               <a href="/cgi-bin/o.pl?file=/a/3.htm">Some text 1</a>
            </li>
            <br>
            <li>
               <a href="/cgi-bin/o.pl?file=/a/33.htm">Some Text 2</a>
            </li>
         </ul>
      </ul>
      <b>February 2017</b>
      <ul>
         <li>
            <b>Part1 1</b>
         </li>
         <ul>
            <li>
               <a href="/cgi-bin/o.pl?file=/b/1.htm">Title 1</a>
            </li>
            <br>
            <li>
               <a href="/cgi-bin/o.pl?file=/b/11.htm">Title 2</a>
            </li>
            <br>
         </ul>
         <li>
            <b>Part1 2</b>
         </li>
         <ul>
            <li>
               <a href="/cgi-bin/o.pl?file=/b/2.htm">Title A</a>
            </li>
            <br>
            <li>
               <a href="/cgi-bin/o.pl?file=/b/22.htm">Title B</a>
            </li>
            <br>
         </ul>
         <li>
            <b>Part1 3</b>
         </li>
         <ul>
            <li>
               <a href="/cgi-bin/o.pl?file=/b/3.htm">Some text 1</a>
            </li>
            <br>
            <li>
               <a href="/cgi-bin/o.pl?file=/b/33.htm">Some Text 2</a>
            </li>
         </ul>
      </ul>
      <b>March 2017</b>
      <ul>
         <li>
            <b>Part1 1</b>
         </li>
         <ul>
            <li>
               <a href="/cgi-bin/o.pl?file=/c/1.htm">Title 1</a>
            </li>
            <br>
            <li>
               <a href="/cgi-bin/o.pl?file=/c/11.htm">Title 2</a>
            </li>
            <br>
         </ul>
         <li>
            <b>Part1 2</b>
         </li>
         <ul>
            <li>
               <a href="/cgi-bin/o.pl?file=/c/2.htm">Title A</a>
            </li>
            <br>
            <li>
               <a href="/cgi-bin/o.pl?file=/c/22.htm">Title B</a>
            </li>
            <br>
         </ul>
         <li>
            <b>Part1 3</b>
         </li>
         <ul>
            <li>
               <a href="/cgi-bin/o.pl?file=/c/3.htm">Some text 1</a>
            </li>
            <br>
            <li>
               <a href="/cgi-bin/o.pl?file=/c/33.htm">Some Text 2</a>
            </li>
         </ul>
      </ul>
   </body>
</html>

我在这里需要的是提取正文标签之间的文本(使用 Scrapy xpath),但我根本不想要表格文本。

我试图获取所有文本的是:

def parse(self, response):
    """
    -*-
    """

    item = DummyItem()

    title = response.xpath('//title/text()').extract()
    body = "\n ".join(
        response.xpath(
            '//body//*[not(self::script or self::style)]/text()'
        ).extract()
    )

    item['title'] = title
    item['body'] = body

    yield item

通过上面的节,我设法提取了我不想要的所有文本,包括表格。 然后我将“body”替换为:

body = "\n ".join(
    response.xpath(
        '//body//*[not(self::table or self::script or self::style)]/text()'
    ).extract()
)

它没有完成这项工作。仍在提取表格文本。

关于如何解决它的任何想法?

【问题讨论】:

  • 如果位于 body 下第一层的不受欢迎的项目改变一点你的 xpath '//body/*[not(self::table or self::script or self::style)]/text()
  • 我认为你希望祖先或自我::表排除任何表和表的任何子项

标签: xpath scrapy


【解决方案1】:

您想要“所有不在&lt;table&gt; 中的文本节点”,或“所有没有&lt;table&gt; 祖先的文本节点”

这是 XPath 中的 /html/body//text()[not(ancestor::table)]

 text_nodes = response.xpath("/html/body//text()[not(ancestor::table)]").extract()

现在您只需要从结果项中去除空格并从列表中删除空字符串。

body = "\n ".join(filter(None, map(str.strip, text_nodes)))

【讨论】:

  • 您的建议有效,但在略有不同的情况下不是 100%。对我来说,问题是我无法用 xPath 术语思考。那么,有什么好的资源可以正确学习 xPath 吗?
  • 恐怕你得自己去找。这里有大量教程、博客文章和文档可供阅读,还有无数关于 SO 的问题涉及特定问题的各个方面。在几个小时内掌握基础知识应该不会太难,恕我直言。
猜你喜欢
  • 2016-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多