我正在加载和滚动动态加载页面。一个例子是Facebook“墙”,只有在你滚动到底部附近的某个地方时才会加载下一个项目。
我滚动直到页面长度很长,然后我复制源代码,将其保存为文本文件并继续解析。
我想提取网页的某些部分。我一直在python中使用lxml module,但成功有限。在那里的网站上,他们只展示了很短的Xpaths的例子。
下面是一个函数示例和一个获取页面上包含的用户名的路径。
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。这些当然更长,更具体。以下是页面上reoccuring元素的示例:
/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-Xpaths,或者有人知道一般使用Xpath的更好方法吗?
使用示例HTML代码和工具like this进行测试,Firebug中的Xpath根本不起作用。这条道路在人们的经历中是否荒谬?
源代码是非常具体的吗?是否有其他工具如Firebug可以生成更可靠的输出以用于lxml?
答案 0 :(得分:1)
FireBug实际上会生成非常差的xpath。它们冗长而脆弱,因为它们在层次结构之外非常具体。 今天的页面非常有活力。
在动态页面上使用xpath的最佳方法是将公共元素定位为钩子,并从那些作为路径根目录执行xpath操作。 我在这里所说的共同元素是稳定的结构元素,很可能或保证存在。根据包含层次结构选择最接近目标的那个。较短的路径更快更清晰。
从那里你需要创建路径,在目标元素上找到一些特定的唯一属性或属性值。 有时候这是不可能的,所以另一个策略是定位最接近的唯一可识别容器元素,然后获得与此类似的所有元素,并迭代它们寻找你的目标。
高度动态的页面需要复杂而动态的方法。
Facebook变化很大,需要经常进行脚本维护。
答案 1 :(得分:0)
我找到了两件对我来说非常好的事情。
第一件事:
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方法更容易要求宽恕而不是许可"在我的情况下应用 - 我接下来要做的就是在TypeError上使用python try
/ except
,我一直看到代码的任意行
这可能是我的代码所特有的,但在检查了很多情况下的输出后,似乎它对我来说效果很好。