当前位置:首页 > 娱乐

python如何爬取网页表格数据

用Python爬网页表格,何爬最直接的取网办法不是去啃复杂的正则表达式,而是页表用pandas库的read_html函数。这个方法能把网页里所有

标签直接变成DataFrame,格数三行代码搞定。何爬

我去年帮朋友抓一个政府招标网站的取网数据,那页面有七八个表格混在一起,页表还有嵌套表格。格数刚开始我用requests加BeautifulSoup,何爬写了一大堆解析逻辑,取网结果网站改版一次就全废了。页表后来换成pandas,格数虽然偶尔会报错,何爬但大部分时候能直接把表格提出来——它内部用的取网是lxml解析器,自动处理了标签嵌套的页表问题。

import pandas as pd url = 'https://example.com/data' tables = pd.read_html(url) df = tables[0] # 第一个表格 print(df.head()) 

注意一个坑:read_html返回的是列表,哪怕页面只有一个表格。你得自己判断哪个索引对应你要的数据。如果表格特别多,可以在参数里加match,比如pd.read_html(url, match='招标'),它只会返回包含“招标”关键词的那个表格。

但read_html不是万能的。遇到动态加载的表格——比如用JavaScript异步请求数据后再渲染的——它就抓瞎了。这时候得请出selenium,模拟浏览器操作。我做过一个股票行情抓取,页面表格是点击“查询”按钮后才出现的,直接read_html拿到的全是空壳。

selenium的流程是:打开浏览器,等页面加载完,模拟点击,等新数据渲染,再抓页面源码。代码长一些,但逻辑清晰:

from selenium import webdriver import time import pandas as pd driver = webdriver.Chrome() driver.get('https://example.com/dynamic-table') time.sleep(3) # 等初始加载 driver.find_element('id', 'searchBtn').click() time.sleep(2) # 等数据刷新 html = driver.page_source df = pd.read_html(html)[0] driver.quit() 

这里有个小技巧:用time.sleep固定等待虽然简单,但网络慢的时候容易失败。更稳妥的是用WebDriverWait,等某个元素出现后再抓数据。不过对于偶尔跑一次的小任务,sleep够用了,别过度设计。

还有个容易忽略的细节:网页表格的表头可能不在<th>标签里,而是用<td>加粗样式冒充的。read_html默认把<th>当列名,遇到这种伪表头,你会得到第一行数据变成列名的结果。解决方法是抓下来后手动把第一行提升为列名:

df.columns = df.iloc[0] df = df[1:] 

最后说下编码问题。中文网页经常是GBK或GB2312编码,read_html有时候会乱码。遇到这种情况,先用requests把页面内容按正确编码解码,再传给read_html:

import requests resp = requests.get(url) resp.encoding = 'gbk' tables = pd.read_html(resp.text) 

实际抓取时,先打开浏览器开发者工具,看看表格是静态HTML还是XHR请求返回的JSON。如果是后者,直接找接口发请求可能比selenium快十倍——但那是另一个话题了。爬表格这件事,八成场景用read_html就够了,别一上来就搞分布式框架,那是杀鸡用牛刀。

分享到: