Python爬取含多个<td>标签的表格方法,Python3指定站点爬表报错求助
Hey,让我们一步步解决你的两个爬虫问题——先从通用的多<td>表格爬取方法说起,再聚焦到你遇到的那个巴西透明门户的具体问题。
问题1:Python中爬取含多个
<td>标签的表格的通用方法 爬取HTML表格的核心是定位表格结构,再遍历行和单元格,这里给你几种常用方案:
静态表格首选:Requests + BeautifulSoup
适合页面内容直接在HTML源码里的场景,步骤清晰可控:import requests from bs4 import BeautifulSoup # 替换成你的目标URL url = "目标页面地址" # 加请求头模拟浏览器,避免被反爬 headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, "html.parser") # 通过表格的id、class或位置定位目标表格 target_table = soup.find("table", class_="表格类名") if target_table: # 遍历所有行(跳过表头可加[1:]) for row in target_table.find_all("tr"): # 获取当前行的所有<td> cells = row.find_all("td") # 提取每个单元格的文本,过滤空内容 row_data = [cell.text.strip() for cell in cells if cell.text.strip()] if row_data: print(row_data) else: print("未找到目标表格")快速方案:Pandas的
read_html()
如果是标准HTML表格,一行代码就能直接转成DataFrame,适合快速提取:import pandas as pd # 自动抓取页面所有表格,返回DataFrame列表 df_list = pd.read_html("目标页面地址", headers={"User-Agent": "你的浏览器UA"}) # 取第一个表格(根据实际情况调整索引) target_df = df_list[0] print(target_df.head())动态表格:Selenium/Playwright
如果表格是JS动态加载的(源码里看不到<td>内容),需要模拟浏览器渲染页面,用Selenium的示例:from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) driver.get("目标页面地址") driver.implicitly_wait(10) # 等待页面加载 # 定位表格并遍历行 rows = driver.find_elements(By.CSS_SELECTOR, "table.表格类名 tr") for row in rows[1:]: # 跳过表头 cells = row.find_elements(By.TAG_NAME, "td") row_data = [cell.text.strip() for cell in cells] print(row_data) driver.quit()
问题2:针对
http://www.portaltransparencia.gov.br/ceis?pagina=1的表格爬取问题 你用linha.find("td")[1]报错,大概率是IndexError——要么某些行的<td>数量不足,要么你定位的linha不是正确的行元素,甚至页面是动态加载导致源码里没有目标内容。给你针对性的解决方案:
第一步:先确认页面是否为静态加载
先验证请求到的源码里是否包含目标内容:
import requests url = "http://www.portaltransparencia.gov.br/ceis?pagina=1" headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"} response = requests.get(url, headers=headers) # 检查是否包含目标区块(实际站点里是class="bloco",可能你拼写成blocos了) print("bloco" in response.text)
如果返回True,说明是静态页面,用BeautifulSoup处理;如果是False,就需要用Selenium模拟浏览器。
第二步:正确定位"bloco"区块内的行和单元格
根据该站点的实际结构,正确的遍历方式应该是:
from bs4 import BeautifulSoup soup = BeautifulSoup(response.text, "html.parser") # 找到所有的bloco区块 blocos = soup.find_all("div", class_="bloco") for bloco in blocos: # 在每个bloco里找到表格行 rows = bloco.find_all("tr") for row in rows: cells = row.find_all("td") # 关键:先判断<td>数量足够再访问索引,避免报错 if len(cells) >= 2: target_content = cells[1].text.strip() print(target_content) else: print("当前行<td>数量不足,跳过")
避坑提醒
- 永远不要直接索引访问
<td>:用try-except或者长度判断兜底,防止因行结构不一致报错:try: target_content = cells[1].text.strip() except IndexError: target_content = "无数据" - 必须加请求头:政府站点反爬严格,不带
User-Agent大概率返回空页面或403。 - 动态加载的应对:如果静态请求拿不到数据,用Selenium模拟浏览器加载页面,再按上述逻辑定位元素即可。
内容的提问来源于stack exchange,提问作者Reinaldo Chaves
相关产品推荐
相关产品推荐

