python爬虫之xpath解析

一起进步吧!感谢大家的支持和关注

xpath 解析

  • 环境安装:pip install lxml

  • xpath解析的编码流程

    • 1.创建一个etree类型的对象,然后把即将被解析的页面源码数据加载到该对象中
    • 2.调用etree对象的xpath方法结合着不同形式的xpath表达式,进行标签定位和数据提取
  • xpath表达式如何理解?

    • html中的标签是遵从树状结构的。

    • xpath表达式中不可以出现tbody标签

    • #from lxml import etree #如果这种方式报错,使用下面方式导入etree
      # from lxml.html import etree
      # fp = open('index.html','r')
      #1.将本地存储好的文件中的数据加载到etree对象中进行数据解析
      #tree = etree.parse(fp)
      #2.调用etree对象的xpath方法结合不同形式的xpath表达式进行标签定位和数据提取
      #xpath返回的一定是列表,列表中存储的是定位到的标签对象
      # title_tag = tree.xpath('/html/head/title')
      # title_tag = tree.xpath('/html//title')
      # title_tag = tree.xpath('//head/title')
      # title_tag = tree.xpath('//title') #推荐
      #最左侧为/:表示必须从树的根标签(html标签)开始进行定位
      #最左侧为//:可以从任意位置进行标签的相对位置定位
      #非最左侧的/:表示一个层级
      #非最左侧的//:表示多个层级
      # tag = tree.xpath('//div') #定位所有的div标签
      
      #属性定位:根据标签的属性定位标签
      #//tagName[@attrName="attrValue"]
      # tag = tree.xpath('//div[@class="song"]')#定位class属性值为song的div标签
      # tag = tree.xpath('//a[@id="feng"]')
      # tag = tree.xpath('//div[@class="tang"]/ul/li/a[@id="feng"]')
      #索引定位:索引是从1开始的
      # tag = tree.xpath('//div[@class="tang"]/ul/li[3]')#定位到第三个li标签
      #获取定位到标签中的文本内容
          # /text()获取标签中直系的文本内容:返回的列表中只会有一个列表元素
          # //text()获取标签中所有的文本内容:通常返回列表中存在多个元素
      # tag = tree.xpath('//div[@class="song"]/p[3]/text()')
      # tag = tree.xpath('//div[@class="song"]//text()')
      #获取定位到标签中的属性值://tag/@attrName
      # tag = tree.xpath('//img/@src')
      #print(tag)
      

### Python 爬虫XPath 解析结果为空的原因及解决方案 在使用 Python 进行爬虫开发时,如果遇到 XPath 解析返回空列表的情况,可能是由以下几个原因引起的: #### 1. HTML 结构不匹配 HTML 页面的实际结构可能与预期不同。浏览器通常会对页面的 HTML 文本进行规范化处理,比如自动添加 `<tbody>` 标签[^4]。这种情况下,即使网页源码中不存在 `<tbody>`,但在浏览器开发者工具中查看时可能会显示该标签。 ##### **解决方案** - 检查实际抓取到的 HTML 数据是否包含目标节点。 - 如果发现存在额外的 `<tbody>` 节点,则需要调整 XPath 表达式以移除这些不必要的部分。 ```python from lxml import etree html_content = """ <table> <tr><td>Example</td></tr> </table> """ tree = etree.HTML(html_content) result = tree.xpath("//table/tbody/tr/td/text()") # 错误示例 print(result) # 输出 [] correct_result = tree.xpath("//table//tr/td/text()") # 正确示例 print(correct_result) # 输出 ['Example'] ``` --- #### 2. 使用绝对路径而非相对路径 当尝试对已经提取的部分 DOM 树再次应用 XPath 时,继续使用 `/` 开头的绝对路径会导致解析失败[^3]。这是因为绝对路径是从整个文档的根节点开始查找,而不是基于当前子树范围内的上下文。 ##### **解决方案** - 将绝对路径改为相对路径,即去掉开头的斜杠 `/` 或者替换为 `.` 来表示当前位置作为起点。 ```python sub_tree = tree.xpath("//div")[0] wrong_sub_result = sub_tree.xpath("/span/text()") # 错误示例 right_sub_result = sub_tree.xpath("./span/text()") # 正确示例 ``` --- #### 3. 特殊字符编码问题 某些网站中的特殊字符(如 Unicode 编码)可能导致解析器无法正确识别内容。这尤其发生在手动拼接字符串或者未设置合适的解码方式的情况下。 ##### **解决方案** - 明确指定请求头中的编码参数; - 利用第三方库 (例如 requests-html) 自动检测并转换响应体的内容类型; ```python import requests from lxml import html response = requests.get('http://example.com', headers={'Accept-Encoding': 'utf-8'}) parser = html.fromstring(response.content.decode('utf-8')) data = parser.xpath('//some_xpath_expression') ``` --- #### 4. 动态加载的数据缺失 现代 Web 应用程序广泛采用 JavaScript 技术动态渲染界面元素。因此通过简单的 HTTP 请求所获得静态资源里未必能捕捉到最终呈现给用户的全部信息。 ##### **解决方案** - 借助 Selenium WebDriver 或 Playwright 工具模拟真实浏览行为直至完成所有异步脚本执行后再抽取所需资料; ```python from selenium import webdriver driver = webdriver.Chrome() driver.get("https://dynamic-content.example") element = driver.find_element_by_xpath('//*[@id="js-rendered"]') # 示例 XPATH content = element.text.strip() driver.quit() ``` --- #### 总结 以上列举了几种常见导致 XPath 返回空白数组的情形及其对应的修正措施。具体操作需视项目需求灵活运用上述技巧组合解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值