【问题标题】:Extracting HTML tag content with xpath from a specific website使用 xpath 从特定网站提取 HTML 标记内容
【发布时间】:2018-12-23 13:49:09
【问题描述】:

我正在尝试使用 lxml 提取网页上特定标签的内容,即在 Indeed.com 上。

示例页面:link

我正在尝试提取公司名称和职位名称。 Chrome显示公司名称位于

"//*[@id='job-content']/tbody/tr/td[1]/div/span[1]"

职位名称位于

"//*[@id='job-content']/tbody/tr/td[1]/div/b/font"

这段代码尝试从本地保存和解析的页面副本中提取这些值:

import lxml.html as h

xslt_root = h.parse("Temp/IndeedPosition.html")
company = xslt_root.xpath("//*[@id='job-content']/tbody/tr/td[1]/div/span[1]/text()")
position = xslt_root.xpath("//*[@id='job-content']/tbody/tr/td[1]/div/b/font/text()")
print(company)
print(position)

但是,打印命令返回空字符串,这意味着没有提取任何内容!

发生了什么事?我使用了正确的标签吗?我不认为这些是动态生成的,因为页面在禁用 javascript 的情况下正常加载。

对于提取这两个值的任何帮助,我将不胜感激。

【问题讨论】:

  • 只是想指出,确实在他们的条款和条件中指定“除非您在与 Indeed 的单独书面协议中明确允许这样做,否则您同意您不会抓取、抓取、复制、复制、复制、出售、交易或转售本网站以用于任何目的”。只是把这个扔出去。我仍然会调查这个问题,假设你不会在确实的法律设置范围之外使用它。
  • 同意。我想指出这个相关的元帖子:meta.stackoverflow.com/questions/329321/…
  • 这是一个公平的观察,@dennlinger。我不会试图摆脱这种困境,只是承认我正在编写一个生成部分个性化求职信的程序。它确实在循环中这样做,它基本上自动化了我一直在使用的复制粘贴过程。我想这属于“抓取”,但我的复制粘贴过程也可能如此。

标签: python html xpath lxml


【解决方案1】:

尽管您假设,页面上的内容似乎是动态加载的,因此在加载期间不存在。
这意味着您无法访问下载的 HTML 文件中的元素(如果您不相信我,请尝试在计算机上的实际文件中查找 job-content,该文件将仅包含占位符和描述符。

看来您必须使用Selenium 之类的技术来执行此任务。 再次强调,无论您(自动)做什么,都违反了 Indeed.com 的条款和条件,因此我建议您无论如何都不要太过分。

【讨论】:

  • 您(部分)正确并提出了一个非常重要的观点。我注意到本地保存的 html 文件要么被正确渲染,要么没有(纯 html 且没有样式)。我已经尝试过请求和 urllib.request - 两者都会随机生成完全呈现的页面或半生不熟的纯 html。我的解决方案是编写一个错误处理程序,尝试使用 wp78de 的解决方案,如果失败,它会使用我发现在“不完整”网页中一致的直接 xpath。
【解决方案2】:

试试这样:

company = xslt_root.xpath("//div[@data-tn-component='jobHeader']/span[@class='company']/text()")
position = xslt_root.xpath("//div[@data-tn-component='jobHeader']/b[@class='jobtitle']//text()")
['The Habitat Company']
['Janitor-A (Scattered Sites)']

一旦我们有了//div[@data-tn-component='jobHeader'] 路径,事情就变得非常简单:

  1. 选择子跨度/span[@class='company']/text()的文本以获取公司名称
  2. /b[@class='jobtitle']//text() 有点复杂:因为职位名称嵌入在字体标签中。但是我们可以使用//text() 选择任何后代文本来获取位置

    另一种方法是选择bfont 节点并使用text_content() 获取文本(如果需要,递归),例如
    xslt_root.xpath("//div[@data-tn-component='jobHeader']/b[@class='jobtitle']")[0].text_content()

【讨论】:

  • 非常感谢!我对 xpath 真的很陌生,真的很欣赏这样的故障。我会将您的帖子标记为答案,但@dennlinger 的帖子还引导我调查页面本地副本的问题,无论是下载并正确引用,还是服务器仅提供没有样式或 JS 的原始 html。
  • @radi0​​ 完全同意,如果您有 15 名声望,您可以继续投票并为答案投票以奖励所付出的努力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-04
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 2017-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多