【问题标题】:Web Scraping using XPath - Not finding element after copying text xpath使用 XPath 进行网页抓取 - 复制文本 xpath 后找不到元素
【发布时间】:2021-10-09 22:01:38
【问题描述】:

尝试从此网页获取特定部分的文本...尝试使用我从类似帖子中找到的代码:

# Import required modules
from lxml import html
import requests
  
# Request the page
page = requests.get('https://www.baseball-reference.com/players/k/kershcl01.shtml')
  
# Parsing the page
tree = html.fromstring(page.content)
  
# Get element using XPath
share = tree.xpath(
    '//div[@id="leaderboard_cyyoung"]/table/tbody/tr[11]/td/a')
print(share)

输出只是空括号[]

【问题讨论】:

  • 从路径的右侧截断路段,直到撞到东西,然后在该点右侧追踪您出错的地方。
  • 你想要的输出具体是什么?

标签: python html xpath python-requests lxml


【解决方案1】:

如上所述,这是网站的渲染/动态部分。它在 cmets 中,因此您需要提取 html 的 cmets,然后进行解析。它的另一个问题是在 cmets 中,没有 <tbody> 标签,所以它找不到任何东西,你需要删除它。不过,我不确定您要提取什么(是链接,还是文本?)。我提醒您的代码向您展示如何将它与 lxml 一起使用,但不是很喜欢。我宁愿只使用 BeautifulSoup。但是 BeautifulSoup 不与 xpath 结合,因此使用了 css 选择器。

您的代码已更改:

import requests
from lxml import html
from bs4 import BeautifulSoup, Comment

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'}

url = "https://www.baseball-reference.com/players/k/kershcl01.shtml"

response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, 'html.parser')
comments = soup.find_all(string=lambda text: isinstance(text, Comment))


for each in comments:
    if 'leaderboard_cyyoung' in str(each):
        htmlStr = str(each)   

        # Parsing the page
        tree = html.fromstring(htmlStr)
          
        # Get element using XPath
        share = tree.xpath('//div[@id="leaderboard_cyyoung"]/table/tr[11]/td/a')
        print(share)

我会怎么做:

import requests
from bs4 import BeautifulSoup, Comment

headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'}

url = "https://www.baseball-reference.com/players/k/kershcl01.shtml"

response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, 'html.parser')
comments = soup.find_all(string=lambda text: isinstance(text, Comment))

for each in comments:
    if 'leaderboard_cyyoung' in str(each):
        soup = BeautifulSoup(str(each), 'html.parser')
        share = soup.select('div#leaderboard_cyyoung > table > tr:nth-child(12) > td > a')
        print(share)
        break

输出:

[<a href="/leaders/mvp_cya.shtml">4.58 Career Shares</a>]

【讨论】:

    【解决方案2】:

    您得到空结果,因为您尝试查询的 div 元素在请求页面的源中被注释掉了。请注意,当您使用 requests.get 方法时,您会得到 页面的 HTML 源代码,而不是浏览器从您与页面的交互中生成的 呈现的 HTML 代码,并且您可以使用浏览器的开发者工具进行检查。

    所以我会说:再次检查这是否真的是您在页面上看到的呈现的元素,看看您是否可以确定是哪种交互方式使它呈现。然后,您可以使用工具来模拟此交互,以便您可以在 Python 环境中获取呈现的 HTML 代码。我建议helium 这样做。如果这不是正确的元素,您可以简单地更新指定的 XPath 以获取正确的源代码可用元素并成功抓取它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-18
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      • 2013-05-21
      • 2016-03-30
      • 1970-01-01
      相关资源
      最近更新 更多