2

这可能是一个非常概念性的问题,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”,如果有其他这样的元素火狐在 XPath 的中间追加/插入,除了 tbody 在尝试获取响应之前我应该​​删除(使用 hxs.select)/构建我的项目管道。

我发现了一个可能的解释:“特别是 Firefox,以向表格添加元素而闻名。另一方面,Scrapy 不会修改原始页面 HTML,因此如果您使用您的 XPath 表达式。” 来源:Firefox,另请参阅: 使用 XPath、Python 和 Scrapy 解析 HTML

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

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

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

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

4

1 回答 1

1

第一季度

通过浏览器添加tbody标签是遵循HTML4 规范的一种方式:

<!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 页面——你有没有看到任何你想抓取的东西?

希望有帮助。

于 2013-07-24T18:24:42.027 回答