如何爬取动态翻页表格数据?解决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
相关产品推荐
相关产品推荐

