
当pandas.read_html无法从网页中提取表格时,通常是因为表格内容是动态加载的,而非直接存在于初始html源码中。本教程将指导您如何利用浏览器开发者工具识别这些动态数据请求(xhr),并通过python的requests库模拟这些请求,直接获取json格式的原始数据,最终使用pandas将其转换为dataframe,从而有效解决动态表格的数据抓取问题。
理解pandas.read_html的局限性
pandas.read_html是一个非常便捷的函数,它能够解析HTML文档中的
标签并将其转换为DataFrame列表。然而,它的工作原理是解析网页的初始HTML源代码。这意味着,如果网页上的表格数据是通过JavaScript在页面加载完成后动态生成的(例如,通过AJAX或XHR请求从后端获取数据并渲染),read_html在检查原始HTML时将无法找到这些表格,从而返回一个空列表。即使使用Selenium等工具获取渲染后的HTML,如果数据本身是通过JavaScript注入到空表格结构中的,get_attribute(‘outerHTML’)也可能返回一个空的表格框架。
识别动态加载的数据源
解决这类问题的关键在于找出JavaScript是从何处获取这些动态数据的。这通常涉及到监控浏览器的网络活动。
打开浏览器开发者工具: 在目标网页上,按下F12键(或右键点击页面选择“检查”),打开开发者工具。切换到“网络”(Network)选项卡: 此选项卡显示了浏览器加载页面时发出的所有请求。筛选XHR/Fetch请求: 在“网络”选项卡中,通常有一个筛选器,选择“XHR”或“Fetch/XHR”。这些是异步JavaScript和XML/HTTP请求,它们通常用于动态加载数据。重新加载页面或触发数据加载: 刷新页面,或者执行任何会触发表格数据显示的操作(例如点击分页、筛选按钮),然后观察XHR请求列表。检查可疑请求: 寻找那些看起来像是获取表格数据的请求。点击这些请求,查看其“标头”(Headers)、“负载”(Payload/Form Data)和“响应”(Response)。请求URL: 这是数据实际发送到的API端点。请求方法: 通常是GET或POST。请求负载/表单数据: 如果是POST请求,这里会包含发送给服务器的参数。响应: 这是服务器返回的数据,通常是JSON格式,也可能是XML或其他文本格式。
通过上述步骤,我们可以发现原始问题中的表格数据并非直接嵌入在HTML中,而是通过一个POST请求发送到https://anex.us/grades/getData/这个URL,并附带了dept和number等参数来获取特定课程的数据。
使用requests库获取动态数据
一旦确定了数据的API端点、请求方法和所需参数,我们就可以使用Python的requests库来模拟这个请求,直接获取原始数据。
立即学习“前端免费学习笔记(深入)”;
import requestsimport pandas as pd# 目标API的URL,通过开发者工具的XHR请求中获取url = 'https://anex.us/grades/getData/'# 请求负载(payload),根据XHR请求的Form Data或Request Payload确定# 这里模拟查询ENGR系102课程的数据payload = {'dept': 'ENGR', 'number': '102'}# 请求头(headers),模拟浏览器行为,特别是User-Agent,以避免被服务器识别为爬虫# User-Agent可以从浏览器开发者工具的Request Headers中复制headers = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0'}# 发送POST请求# 对于GET请求,应使用 requests.get(url, params=payload, headers=headers)response = requests.post(url, data=payload, headers=headers)# 检查请求是否成功(状态码200)response.raise_for_status() # 如果请求失败,会抛出HTTPError# 解析JSON响应# 大多数动态数据API会返回JSON格式data = response.json()# 将JSON数据转换为Pandas DataFrame# 根据JSON结构,数据通常嵌套在某个键下,例如这里的'classes'df = pd.DataFrame(data['classes'])# 打印DataFrame的前几行以验证数据print(df.head())
输出示例:
dept number section A B C D F I S U Q X prof year semester gpa0 ENGR 102 20 18 17 8 2 3 0 0 0 1 0 AMINI N 2018 FALL 2.93751 ENGR 102 21 18 31 15 4 1 0 0 0 0 0 KOOLA P 2018 FALL 2.884057971014492 ENGR 102 22 10 28 16 2 3 0 0 0 0 0 SHAW S 2018 FALL 2.677966101694923 ENGR 102 26 9 24 10 4 6 0 0 0 0 0 SUBRAMANIAN R 2018 FALL 2.490566037735854 ENGR 102 201 21 12 1 1 0 0 0 0 0 0 IJAZ M 2018 FALL 3.51428571428571
注意事项与最佳实践
User-Agent的重要性: 在headers中设置User-Agent可以模拟真实的浏览器请求,这对于避免某些网站的反爬机制非常重要。请求方法(GET vs. POST): 根据开发者工具中XHR请求的“方法”字段,选择requests.get()或requests.post()。GET请求的参数通常通过params字典传递,而POST请求的参数通过data字典(或json字典,如果发送JSON数据)传递。响应数据格式: 大多数现代Web API返回JSON格式的数据,可以直接使用response.json()解析。如果响应是其他格式(如XML、CSV、纯文本),则需要使用相应的库或方法进行解析。错误处理: 始终添加错误处理机制,例如使用response.raise_for_status()检查HTTP状态码,或者使用try-except块处理网络请求或JSON解析错误。网站使用条款: 在抓取任何网站数据之前,请务必查阅其robots.txt文件和使用条款,确保您的行为符合规定,避免对网站服务器造成不必要的负担。何时使用无头浏览器: 如果通过XHR请求仍然无法获取到完整或正确的数据,或者数据在客户端经过复杂的JavaScript处理才最终呈现,那么使用无头浏览器(如Selenium配合Chrome/Firefox)可能是唯一的选择。然而,直接模拟API请求通常效率更高、资源消耗更少。
总结
当pandas.read_html无法正常工作时,通常意味着数据是动态加载的。通过熟练运用浏览器开发者工具,我们可以“窥探”到网页背后数据流动的秘密,识别出数据源的API请求。随后,利用requests库模拟这些请求,直接获取原始数据(通常是JSON),并结合pandas进行数据清洗和结构化,就能高效、精准地抓取到所需信息。这种方法不仅解决了read_html的局限性,也为处理更复杂的动态网页数据提供了强大的解决方案。
以上就是解决Pandas read_html无法识别动态加载表格的问题的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1380052.html
微信扫一扫
支付宝扫一扫