获取响应元素的差异:Scrapy中使用Firebug和XPath检查器扩展的绝对和相对XPath



这可能是一个非常概念性的问题,Stack overflow在scratchy和构建Xpath方面拥有丰富的资源,但我没有找到任何具体的答案,所以我要问。

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

更具体地说-

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

碎屑状外壳http://www.ebay.com/sch/Coats-Jackets-/57988/i.html

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

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

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

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

--在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/dv/div[2]/h4/a/@hrefhxs.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[2]/h4/a/@href").textract()即使在删除tbody后也不起作用

请注意,只有在从XPath中显式删除"tbody"之后,我才会看到响应,但对于通过Firepath生成的绝对路径,这并不适用。

Q1:为什么我需要删除"tbody",如果firefox在XPath中间附加/插入了其他这样的元素,那么除了tbody之外,我应该在尝试获取响应(使用hxs.select)/构建项目管道之前删除它。

我发现了一个可能的解释:"尤其是Firefox,它以向表中添加元素而闻名。另一方面,Scrapy不会修改原始页面HTML,因此如果在XPath表达式中使用,则无法提取任何数据。"来源:Firefox,另请参阅:使用XPath、Python和Scrapy 解析HTML

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

Q3:Firebug和;XPath检查器工作得更好(读起来更健壮/一致)——如果是,为什么?

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

相关-表中的Xpath表使用XPath、Python和Scrapy 解析HTML

Q1

浏览器添加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>在HTML5中
  • 为什么firebug添加<tbody>至<表>

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

第二季度

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

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

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

另请参阅:

  • scrapy可以用来从使用AJAX的网站上抓取动态内容吗
  • 使用python擦除ajax页面
  • 这个和这个片段(硒+碎屑)

第三季度

这真的取决于你。如果您要继续使用Scrapy,那么只需在xpath检查器或FirePath中构造xpath,并在Scrapy shell中进行检查,这一点很重要。

Q4

我会这样回答:禁用JS并加载这个ebay页面——你看到你想刮的东西了吗?

希望能有所帮助。

最新更新