使用 Scrapy 抓取网页时 tbody 为空的问题及解决方案

花韻仙語
发布: 2025-07-12 16:02:18
原创
165人浏览过

使用 scrapy 抓取网页时 tbody 为空的问题及解决方案

本文旨在解决在使用 Scrapy 爬取网页数据时,XPath 表达式中包含 tbody 元素导致返回空数组的问题。通常,tbody 元素是由浏览器动态添加的,并不存在于原始 HTML 源码中。本文将提供绕过 tbody 元素直接提取所需数据的有效方法,并给出相应的 Scrapy Shell 示例。

在使用 Scrapy 进行网页抓取时,你可能会遇到这样的问题:你通过浏览器开发者工具检查元素时,发现某个元素位于 tbody 标签内,但在 Scrapy 中使用 XPath 表达式尝试提取该元素时,却得到了一个空数组。这通常是因为 tbody 元素是由浏览器在渲染页面时动态添加的,实际上并不存在于服务器返回的原始 HTML 源码中。

问题分析

浏览器为了更好地组织表格数据,会自动在 table 标签内插入 tbody 标签。然而,这个 tbody 标签并非总是存在于服务器返回的原始 HTML 中。当你使用 Scrapy 获取网页内容时,你得到的是原始 HTML,而不是浏览器渲染后的 DOM 结构。因此,如果你的 XPath 表达式依赖于 tbody 标签,那么很可能会得到空结果。

解决方案

解决这个问题的方法是绕过 tbody 标签,直接定位到你想要提取的元素。以下提供两种常用的方法:

  1. 直接定位到 tr 元素:

    如果你的目标是提取表格中的所有行 (tr 元素),可以直接从包含表格的 div 元素开始,跳过 tbody 标签,直接定位到 tr 元素。

    例如,假设你的 HTML 结构如下:

    <div id="TableWithRules">
      <table>
        <thead>
          <tr>
            <th>Header 1</th>
            <th>Header 2</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Row 1, Column 1</td>
            <td>Row 1, Column 2</td>
          </tr>
          <tr>
            <td>Row 2, Column 1</td>
            <td>Row 2, Column 2</td>
          </tr>
        </tbody>
      </table>
    </div>
    登录后复制

    你可以使用以下 XPath 表达式来提取所有行:

    //div[@id='TableWithRules']//tr
    登录后复制

    在 Scrapy Shell 中,你可以这样使用:

    scrapy shell https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=hp
    登录后复制
    rows = response.xpath("//div[@id='TableWithRules']//tr")
    print(len(rows)) # 输出行数
    登录后复制
  2. 跳过表头行:

    如果你的表格包含表头行 (th 元素),并且你只想提取数据行 (td 元素),可以使用 XPath 的谓词来过滤掉表头行。

    //div[@id='TableWithRules']//tr[td]
    登录后复制

    这个 XPath 表达式会选择所有包含 td 元素的 tr 元素,从而排除表头行。

    在 Scrapy Shell 中,你可以这样使用:

    rows = response.xpath("//div[@id='TableWithRules']//tr[td]")
    print(len(rows)) # 输出数据行数
    登录后复制

示例代码

以下是一个完整的 Scrapy 示例,展示了如何使用上述方法提取表格数据:

import scrapy

class MySpider(scrapy.Spider):
    name = "mytablecrawler"
    start_urls = ['https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=hp']

    def parse(self, response):
        rows = response.xpath("//div[@id='TableWithRules']//tr[td]")
        for row in rows:
            # 提取每一行的数据
            data = row.xpath("./td/text()").getall()
            yield {
                'column1': data[0] if len(data) > 0 else None,
                'column2': data[1] if len(data) > 1 else None,
                # ... 其他列
            }
登录后复制

注意事项

  • 在编写 XPath 表达式时,务必仔细检查网页的 HTML 结构,并根据实际情况进行调整。
  • 如果网页的 HTML 结构比较复杂,可能需要使用更复杂的 XPath 表达式才能准确地提取到所需数据。
  • 有些网站可能会使用 JavaScript 动态生成表格数据,这种情况下,可能需要使用 Selenium 等工具来模拟浏览器行为,才能获取到完整的数据。

总结

当在使用 Scrapy 抓取网页数据时,遇到 tbody 为空的问题,不要慌张。首先要理解 tbody 元素可能并不存在于原始 HTML 源码中。然后,尝试绕过 tbody 标签,直接定位到你想要提取的元素。通过灵活运用 XPath 表达式,你就可以轻松地解决这个问题,并成功地抓取到所需的数据。

以上就是使用 Scrapy 抓取网页时 tbody 为空的问题及解决方案的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号