使用 Python 进行抓取和解析 - 具有长 Xpath 的 lxml
Scraping and parsing with Python - lxml with long Xpaths
我正在动态加载页面上加载和滚动。一个例子是 Facebook "wall",它只会在您滚动到底部附近的某个位置后加载下一个项目。
我滚动直到页面很长,然后我复制源代码,将其保存为文本文件并继续解析它。
我想提取网页的某些部分。我一直在 python 中使用 lxml module,但收效甚微。在该网站上,他们只显示 Xpath 非常短的示例。
下面是函数示例和获取页面上包含的用户名的路径。
usersID = elTree.xpath('//a[@class="account-group js-account-group js-action-profile js-user-profile-link js-nav"]')
这很好用,但是我得到了一些 (我的另一个 post),例如:
TypeError: 'NoneType' object has no attribute 'getitem'
我也一直在查看 Firebug 提供的 Xpath。这些当然要长得多而且非常具体。这是页面上重复出现的元素的示例:
/html/body/div[2]/div[2]/div/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/ol[1]/li[26]/ol/li/div/div[2]/p
最后的部分 li[26]
显示它是同一元素列表中的第 26 项,它们位于 HTML 树的同一级别。
我想知道我如何将这样的 firebug-Xpaths 与 lxml 库一起使用,或者有人知道一般使用 Xpaths 的更好方法吗?
使用示例 HTML 代码和工具 like this 进行测试,来自 Firebug 的 Xpath 根本不起作用。这条路在人们的经验中是不是很可笑?
是不是很具体的源代码?有没有像 Firebug 这样的其他工具可以生成更可靠的输出以用于 lxml?
FireBug 实际上生成了非常糟糕的 xpath。它们又长又脆弱,因为它们在层次结构之外非常不具体。
今天的页面非常动态。
在动态页面上使用 xpath 的最佳方法是将公共元素定位为挂钩,然后从这些元素作为路径根执行 xpath 操作。
我在这里所说的共同元素是指极有可能或保证存在的稳定结构元素。选择在遏制层次结构方面最接近您的目标的一个。更短的路径更快更清晰。
从那里您需要创建路径来定位目标元素上的某些特定的唯一属性或属性值。
有时这是不可能的,所以另一种策略是定位最接近的唯一可识别容器元素,然后在其下获取所有与您的元素相似的元素,并迭代它们以寻找您的目标。
高度动态的页面需要复杂的动态方法。
Facebook变化很大,需要经常维护脚本。
我发现有两件事对我来说非常有效。
第一件事:
lxml 包允许结合 Xpath 使用一些函数。我用的是starts-with
函数,如下:
tweetID = elTree.xpath("//div[starts-with(@class, 'the-non-varying-part-of-a-very-long-class-name')]")
在使用 Firebug/Firepath 等工具探索 HTML 代码(树)时,一切都显示得很漂亮和整齐 - 例如:
*
*
当我使用突出显示的路径,即 tweet original-tweet js-original-tweet js-stream-tweet js-actionable-tweet js-profile-popup-actionable has-cards has-native-media with-media-forward media-forward cards-forward
- 在上面的代码中搜索我的 elTree 时,没有找到任何东西。
查看我试图解析的实际 HTML 文件,我发现它确实分布在很多行中 - 如下所示:
这解释了为什么根据我的搜索找不到 lxml 包。
第二件事:
我知道通常不建议将其作为解决方法,但 Python 方法 "easier to ask for forgiveness than permission" 适用于我的案例 - 我接下来要做的是使用 python try
/ except
一个 TypeError,我在看似随意的代码行中不断遇到这种错误
这很可能是我的代码所特有的,但在检查了很多情况下的输出后,它似乎对我来说效果很好。
我正在动态加载页面上加载和滚动。一个例子是 Facebook "wall",它只会在您滚动到底部附近的某个位置后加载下一个项目。
我滚动直到页面很长,然后我复制源代码,将其保存为文本文件并继续解析它。
我想提取网页的某些部分。我一直在 python 中使用 lxml module,但收效甚微。在该网站上,他们只显示 Xpath 非常短的示例。
下面是函数示例和获取页面上包含的用户名的路径。
usersID = elTree.xpath('//a[@class="account-group js-account-group js-action-profile js-user-profile-link js-nav"]')
这很好用,但是我得到了一些
TypeError: 'NoneType' object has no attribute 'getitem'
我也一直在查看 Firebug 提供的 Xpath。这些当然要长得多而且非常具体。这是页面上重复出现的元素的示例:
/html/body/div[2]/div[2]/div/div[2]/div[2]/div/div[2]/div/div/div/div/div[2]/ol[1]/li[26]/ol/li/div/div[2]/p
最后的部分 li[26]
显示它是同一元素列表中的第 26 项,它们位于 HTML 树的同一级别。
我想知道我如何将这样的 firebug-Xpaths 与 lxml 库一起使用,或者有人知道一般使用 Xpaths 的更好方法吗?
使用示例 HTML 代码和工具 like this 进行测试,来自 Firebug 的 Xpath 根本不起作用。这条路在人们的经验中是不是很可笑?
是不是很具体的源代码?有没有像 Firebug 这样的其他工具可以生成更可靠的输出以用于 lxml?
FireBug 实际上生成了非常糟糕的 xpath。它们又长又脆弱,因为它们在层次结构之外非常不具体。 今天的页面非常动态。
在动态页面上使用 xpath 的最佳方法是将公共元素定位为挂钩,然后从这些元素作为路径根执行 xpath 操作。 我在这里所说的共同元素是指极有可能或保证存在的稳定结构元素。选择在遏制层次结构方面最接近您的目标的一个。更短的路径更快更清晰。
从那里您需要创建路径来定位目标元素上的某些特定的唯一属性或属性值。 有时这是不可能的,所以另一种策略是定位最接近的唯一可识别容器元素,然后在其下获取所有与您的元素相似的元素,并迭代它们以寻找您的目标。
高度动态的页面需要复杂的动态方法。
Facebook变化很大,需要经常维护脚本。
我发现有两件事对我来说非常有效。
第一件事:
lxml 包允许结合 Xpath 使用一些函数。我用的是starts-with
函数,如下:
tweetID = elTree.xpath("//div[starts-with(@class, 'the-non-varying-part-of-a-very-long-class-name')]")
在使用 Firebug/Firepath 等工具探索 HTML 代码(树)时,一切都显示得很漂亮和整齐 - 例如:
*
*
当我使用突出显示的路径,即 tweet original-tweet js-original-tweet js-stream-tweet js-actionable-tweet js-profile-popup-actionable has-cards has-native-media with-media-forward media-forward cards-forward
- 在上面的代码中搜索我的 elTree 时,没有找到任何东西。
查看我试图解析的实际 HTML 文件,我发现它确实分布在很多行中 - 如下所示:
这解释了为什么根据我的搜索找不到 lxml 包。
第二件事:
我知道通常不建议将其作为解决方法,但 Python 方法 "easier to ask for forgiveness than permission" 适用于我的案例 - 我接下来要做的是使用 python try
/ except
一个 TypeError,我在看似随意的代码行中不断遇到这种错误
这很可能是我的代码所特有的,但在检查了很多情况下的输出后,它似乎对我来说效果很好。