You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何爬取动态翻页表格数据?解决Employbl网站爬取翻页难题

解决动态分页的爬取问题

当前代码无法获取更多数据的核心原因是:页面的分页是JavaScript动态加载的,点击「下一页」时不会跳转新URL,而是通过异步请求后端API获取数据,静态请求页面的方式无法捕获这些动态加载的内容。

解决方案步骤

1. 定位分页API接口

打开浏览器开发者工具(F12),切换到「网络」标签页,点击页面的「下一页」按钮,观察新出现的请求。你会发现一个类似/api/company-locations/los-angeles?page=2&per_page=100的API请求,它返回的是JSON格式的分页公司数据。

2. 修改代码直接请求API

不再解析HTML分页按钮,改为循环请求API接口,传入不同的page参数获取所有页的公司数据,再爬取详情页。

修改后的完整代码

import pandas as pd
import requests
from bs4 import BeautifulSoup

# 爬取公司详情页的函数(保留原有逻辑,添加请求异常处理)
def scrape_company_info(company_url):
    company_data = {}
    try:
        # 添加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"}
        company_page = requests.get(company_url, headers=headers)
        company_page.raise_for_status()
        company_soup = BeautifulSoup(company_page.text, 'html.parser')

        company_data['Company Name'] = company_soup.find('h1', class_='mt-3').text.strip()
        company_data['Location'] = company_soup.find('p', class_='mt-3 text-xl italic text-gray-500').text.strip()
        company_data['Description'] = company_soup.find('p', class_='mt-3 mb-1').text.strip()
    
        website_link = company_soup.find('a', class_='flex items-center justify-center text-base font-medium text-indigo-600 sm:justify-start')
        if website_link:
            company_data['Website'] = website_link['href']
    
        company_info_dl = company_soup.find('dl', class_='grid grid-cols-1 gap-x-4 gap-y-8 px-6 pb-6 sm:grid-cols-2')
        if company_info_dl:
            for dt, dd in zip(company_info_dl.find_all('dt', class_='text-base font-medium text-gray-500'),
                              company_info_dl.find_all('dd', class_='text-3xl font-extrabold tracking-tight text-gray-900')):
                company_data[dt.find('h2').text] = dd.text
    except AttributeError:
        print(f"跳过公司,AttributeError: {company_url}")
        return None
    except requests.exceptions.RequestException as e:
        print(f"请求详情页失败: {e}")
        return None
    
    return company_data

# 初始化存储列表(原代码错误写成字典,此处修正)
data = []
base_api_url = "https://www.employbl.com/api/company-locations/los-angeles"
page = 1
per_page = 100

while True:
    # 请求API接口,传入分页参数
    api_params = {"page": page, "per_page": per_page}
    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(base_api_url, params=api_params, headers=headers)
    
    if response.status_code != 200:
        print(f"第{page}页API请求失败,状态码: {response.status_code}")
        break
    
    api_data = response.json()
    # 检查当前页是否有数据
    if not api_data.get("companies"):
        break
    
    # 遍历当前页的公司,爬取详情
    for company in api_data["companies"]:
        company_slug = company["slug"]
        company_url = f"https://www.employbl.com/companies/{company_slug}"
        print(f"正在爬取公司: {company['name']}")
        company_info = scrape_company_info(company_url)
        if company_info:
            data.append(company_info)
    
    # 检查是否还有下一页
    total_pages = api_data.get("total_pages", 1)
    if page >= total_pages:
        break
    
    page += 1

# 生成DataFrame并可选保存
df = pd.DataFrame(data)
print(df.head())
# df.to_csv("los_angeles_companies.csv", index=False)

注意事项

  • 请根据浏览器实际捕获的API响应,调整代码中api_data["companies"]、total_pages等字段名,确保和接口返回的JSON结构一致。
  • 替换User-Agent为你当前浏览器的标识,降低被反爬拦截的概率。
  • 原代码中data = {}是错误写法,必须改为data = []才能使用append方法添加数据。

内容的提问来源于stack exchange,提问作者Ella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 08:37:49