使用BeautifulSoup爬取Payscale大学薪资报告数据失败求助
BeautifulSoup爬取Payscale大学薪资报告数据失败求助
你好呀!看了你遇到的问题——用BeautifulSoup爬取Payscale的大学薪资报告时,不管用find_all还是find都拿不到表格数据,甚至试了Selenium也没解决,我来帮你排查下可能的原因和解决方案~
先说说问题的核心原因
大概率是以下几个情况之一:
- 网站反爬拦截了请求:requests默认的请求头会暴露你是爬虫程序,Payscale直接拒绝了数据请求,导致你拿到的页面根本没有表格内容;
- 页面结构已更新:你用的
data-table这个class名称可能已经被网站修改,自然找不到对应的表格; - 表格是动态渲染的:如果表格内容是通过JavaScript加载的,单纯用requests只能拿到静态HTML,看不到动态生成的表格。
一步步的解决方案
第一步:解决请求被拦截的问题
先给requests加上模拟浏览器的请求头,试试能不能拿到完整页面内容:
import pandas as pd import requests from bs4 import BeautifulSoup # 模拟浏览器的请求头,可换成自己浏览器的User-Agent 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' } url = "https://www.payscale.com/college-salary-report/majors-that-pay-you-back/bachelors" response = requests.get(url, headers=headers) # 先检查请求是否成功,状态码200代表请求正常 print(f"请求状态码:{response.status_code}") if response.status_code == 200: soup = BeautifulSoup(response.text, "html.parser") # 查看页面里总共有多少个表格,确认是否能拿到内容 all_tables = soup.find_all('table') print(f"找到的表格数量:{len(all_tables)}") if all_tables: # 打印第一个表格的class,确认是不是你用的data-table print(f"第一个表格的class属性:{all_tables[0].get('class')}") else: print(f"请求失败了,状态码:{response.status_code}")
如果运行后能看到表格数量大于0,说明请求成功,接下来就可以根据实际的class名称定位表格;如果还是0,那大概率是动态加载的问题,得用Selenium处理。
第二步:用Selenium处理动态加载内容
如果表格是JavaScript动态生成的,就得用Selenium模拟浏览器加载页面,等内容渲染完成后再抓取:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from bs4 import BeautifulSoup import pandas as pd # 初始化浏览器驱动,确保已安装对应浏览器的驱动(比如ChromeDriver) driver = webdriver.Chrome() url = "https://www.payscale.com/college-salary-report/majors-that-pay-you-back/bachelors" driver.get(url) try: # 等待表格加载完成,最多等10秒 table = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "data-table")) ) # 获取表格的完整HTML内容 table_html = table.get_attribute('outerHTML') soup = BeautifulSoup(table_html, "html.parser") # 解析表头和数据行 header_cells = soup.find_all('th') headers = [cell.text.strip() for cell in header_cells] data_rows = [] # 跳过表头行,遍历数据行 for row in soup.find_all('tr')[1:]: row_cells = row.find_all('td') row_data = [cell.text.strip() for cell in row_cells] data_rows.append(row_data) # 转成DataFrame,方便后续处理 df = pd.DataFrame(data_rows, columns=headers) print("爬取到的前5条数据:") print(df.head()) finally: # 不管成功失败,最后都关闭浏览器 driver.quit()
如果还是找不到表格,记得打开浏览器开发者工具,重新确认表格的class名称,把By.CLASS_NAME后面的参数换成实际的class即可。
第三步:翻页数据的处理
如果要爬取多页数据,用Selenium可以这么做:
- 在循环里找到下一页按钮并点击;
- 每次点击后等待页面加载完成,再抓取当前页的表格数据;
- 直到下一页按钮不可点击(比如class包含disabled)为止。
额外小建议
如果不想用Selenium,也可以试试浏览器开发者工具的Network面板,看看网站是不是通过API接口加载表格数据的。如果能找到对应的API,直接请求接口拿JSON数据会比解析HTML高效得多,也更稳定。
备注:内容来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

