【问题标题】:Difference in fetching response elements : Absolute and relative XPath in Scrapy using Firebug and XPath Checker extensions获取响应元素的区别:使用 Firebug 和 XPath Checker 扩展的 Scrapy 中的绝对和相对 XPath
【发布时间】:2013-07-24 07:06:31
【问题描述】:

这可能是一个非常概念性的问题,Stack Overflow 有丰富的关于 scrapy 和构建 Xpaths 的资源 - 但我没有找到任何具体回答这个问题的东西,所以问。

在使用 Firebug 和 XPath 检查器(独立地)为 Scrapy(在 python 中)构建我的 XPath 表达式时 - 我看到了两种不同的方式来构建我的 Xpath。我知道对于特定的 Xpath/HTML 层次结构,可以有许多可能的方法来构建 XPath,以便能够提取/抓取感兴趣的元素。我也知道您可以生成绝对/相对 Xpath(在 Firepath 中)

更具体地说-

示例用例 -- 尝试在 ebay 上抓取页面

scrapy shell http://www.ebay.com/sch/Coats-Jackets-/57988/i.html

--使用 Xpath 检查器-- [工作正常,从 XPath 中删除 tbody 后]]

Xpath = id('ResultSetItems')/table/tbody/tr/td/div/div/div/div/div/h4/a/text() hxs.select("id('ResultSetItems')/table/tr/td/div/div/div/div/div/h4/a/text()").extract()

-- 在 Firepath 中使用相对路径-- [在从 XPath 中删除 tbody 后有效,可以]

XPath = .//[@id='ResultSetItems']/table[1]/tbody/tr/td[1]/div/div/div/div/div[2]/h4/a /@href hxs.select(".//[@id='ResultSetItems']/table[1]/tr/td[1]/div/div/div/div/div[2]/h4/a/ @href").extract()

-- 在 Firepath 中使用绝对路径-- [不起作用,即使在从 XPath 中删除 tbody 之后]

XPath = =html/body/div[5]/div[2]/div[3]/div[1]/div/div/div[2]/div/div[6]/div/table[ 1]/tbody/tr/td[1]/div/div/div/div/div[2]/h4/a/@href hxs.select("html/body/div[5]/div[2]/div[3]/div[1]/div/div/div[2]/div/div[6]/div/table[1 ]/t>r/td[1]/div/div/div/div/div[2]/h4/a/@href").extract() 不起作用,即使在删除 tbody 之后

请注意,我只有在从 XPath 中明确删除“tbody”后才能看到响应,但这不适用于通过 Firepath 生成的绝对路径。

Q1:为什么我需要删除“tbody”,如果还有其他这样的元素,Firefox 会在 XPath 中间追加/插入,除了在尝试获取之前我应该​​删除的 tbody响应(使用 hxs.select)/构建我的项目管道。

我发现的一个可能的解释是:“特别是 Firefox,以向表格添加元素而闻名。另一方面,Scrapy 不会修改原始页面 HTML,因此如果出现以下情况,您将无法提取任何数据您在 XPath 表达式中使用。" 来源:Firefox,另见:Parsing HTML with XPath, Python and Scrapy

Q2:在 FirePath 窗格中读取绝对路径时,即使删除 tbody 后响应也不起作用 - 为什么会这样?

Q3 : 是否有最佳实践说明 Firebug 和 XPath 检查器之间的哪一个效果更好(阅读更健壮/一致) - 如果是,为什么以及哪一个?

Q4 不相关:有些人建议在构建 XPath 时在浏览器上禁用 Javascript,这是否相关并且禁用 JavaScript 是一种标准做法?在刮(如果有的话)时不这样做会有什么影响?

相关 - Xpath Table Within Table Parsing HTML with XPath, Python and Scrapy

【问题讨论】:

    标签: xpath python-2.7 html-parsing firebug scrapy


    【解决方案1】:

    第一季度

    浏览器添加tbody标签是一种追随HTML4 specification的方式:

    <!ELEMENT TABLE - -
         (CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)>
    <!ATTLIST TABLE                        -- table element --
      %attrs;                              -- %coreattrs, %i18n, %events --
      summary     %Text;         #IMPLIED  -- purpose/structure for speech output--
      width       %Length;       #IMPLIED  -- table width --
      border      %Pixels;       #IMPLIED  -- controls frame width around table --
      frame       %TFrame;       #IMPLIED  -- which parts of frame to render --
      rules       %TRules;       #IMPLIED  -- rulings between rows and cols --
      cellspacing %Length;       #IMPLIED  -- spacing between cells --
      cellpadding %Length;       #IMPLIED  -- spacing within cells --
      >
    

    换句话说,根据规范,tr 元素不能是table 的直接子元素。当浏览器发现tbody 丢失时,它会插入它。另一方面,HTML5 允许这样做。浏览器现在只是为了向后兼容而保留它。

    另见:

    通常,您应该只关注tbody,但理论上,浏览器可以更改/注入/修复页面的 html 以使其正常工作。

    第二季度

    这个特定的 ebay 页面使用 js 来动态加载内容。 Scrapy 在“Body” div (div[5]) 中只看到 1 个 div:

    >>> hxs.select('//html/body/div[5]/div').extract()
    [u'<div id="showDiagContainer">\r\n</div>']
    

    其他 div 是通过 ajax 请求加载的。通常这是 Scrapy 的一个问题,您必须处理并找到解决方法。两种选择:在蜘蛛中模拟这些 ajax 调用或切换到浏览器内工具,如 selenium(或将其与 Scrapy 结合使用)。

    另见:

    第三季度

    这完全取决于您。如果您将继续使用 Scrapy - 那么,只需在 Xpath 检查器或 FirePath 中构造 xpath 并在 scrapy shell 中检查它 - 这很重要。

    第四季度

    我会这样回答:禁用 JS 并加载这个 ebay 页面 - 你看到任何你想抓取的东西吗?

    希望对您有所帮助。

    【讨论】:

    • 感谢@alecxe 非常有用的帖子。 Q1:除了tbody,thead和tfoot也插入了吗? Q2:有没有更简单的方法可以知道网页使用了 AJAX ?我理解“他的“XML Http 请求”是用于向服务器发送 Ajax 请求的协议,因此存在这样的请求表明正在进行基于 Ajax 的操作”——但我如何才能在 Firepath 中看到我的 XPath 时知道它(因此编写我自己的代码来处理此类动态页面),Selenium 是唯一的方法吗? Scrapy+AJAX 链接提到了如何处理它,需要关于如何知道它的 AJAX 的指针。如果在其他地方很好地覆盖,请重定向我。
    • 不客气。 Q1:theadtfoot 是可选的,浏览器不会自动注入它们。 Q2:在firebug中使用Net标签,或者在chrome开发工具中使用network;过滤所有XHR 请求,看看是否有任何东西。然后,您可以使用RequestFormRequestFormRequest.from_response 在Scrapy 中模拟这些XHR 请求。但是,有时页面加载过于复杂,无法通过 scrapy 实现自动化,而 selenium 是一种可行的方法。顺便说一句,Selenium 可以与 phantomJS 这样的无头浏览器一起使用。
    • 另外,看看scrapy sn-ps的列表:snipplr.com/all/tags/scrapy。在 selenium 中使用 scrapy 有一些很好的例子,例如 herehere
    猜你喜欢
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多