使用Python-lxml和长xpath进行抓取和解析

2024-03-28 22:47:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我在动态加载页面上加载和滚动。一个例子是Facebook的“墙”,它只在你滚动到靠近底部的某个地方时加载下一个项目。你知道吗

我滚动直到页面变长,然后复制源代码,将其保存为文本文件并继续解析。你知道吗

我想提取网页的某些部分。我一直在使用python中的lxml module,但效果有限。在那里的网站上,他们只显示了很短的xpath的例子。你知道吗

下面是一个函数示例和一个路径,它可以让我获得页面上包含的用户名。你知道吗

usersID = elTree.xpath('//a[@class="account-group js-account-group js-action-profile js-user-profile-link js-nav"]')

这工作得相当好,但是我得到了一些errors(我的另一篇文章),例如:

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树的同一级别。你知道吗

我想知道如何在lxml库中使用这样的firebug xpath,或者有谁知道如何更好地使用xpath?你知道吗

使用示例HTML代码和工具like this进行测试,Firebug的xpath根本不起作用。在人们的经验中,这条路是不是太荒谬了?你知道吗

是非常具体的源代码吗?有没有像Firebug这样的工具可以产生更可靠的输出来与lxml一起使用?你知道吗


Tags: div元素示例源代码jsgroupaccount页面
2条回答

萤火虫产生的xpath真的很差。它们又长又脆弱,因为它们的非特定性超出了等级体系。 今天的页面非常动态。你知道吗

在动态页面上使用xpath的最佳方法是将公共元素定位为钩子,并从作为路径根的元素执行xpath操作。 我这里所说的共同元素是指稳定的结构元素,它们很可能存在或保证存在。从包含层次结构的角度选择最接近目标的一个。较短的路径更快更清晰。你知道吗

从那里您需要创建路径来定位目标元素上的某些特定的唯一属性或属性值。 有时这是不可能的,所以另一个策略是以最接近的唯一可识别的容器元素为目标,然后在该容器下获取与您的元素相似的所有元素,并迭代它们以寻找您的目标。你知道吗

高度动态的页面需要复杂的动态方法。你知道吗

Facebook变化很大,需要经常维护脚本。你知道吗

我发现有两件事对我很有帮助。你知道吗

第一件事:

lxml包允许结合Xpath使用一些函数。我使用了^{}函数,如下所示:

tweetID = elTree.xpath("//div[starts-with(@class, 'the-non-varying-part-of-a-very-long-class-name')]")

当使用诸如Firebug/Firepath之类的工具浏览HTML代码(树)时,所有内容都显示得很好、整洁—例如:

Xpath and class name in Firebug

当我使用高亮显示的路径,即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文件,我发现它实际上分布在许多行中—如下所示:

Actual HTML code

这就解释了为什么lxml包没有根据我的搜索找到它。你知道吗

第二件事:

我知道一般不推荐使用Python方法作为解决方法,但是在我的例子中应用了Python方法,即“请求原谅比请求许可更容易”——接下来我做的事情是使用Python ^{} / ^{}处理一个类型错误,我一直在处理代码中看似任意的行

这可能是特定于我的代码的,但是在检查了许多情况下的输出之后,它似乎对我很有效。你知道吗

相关问题 更多 >