BeautifulSoup爬取Upwork职位标题返回空列表如何解决
问题根因
- 基础反爬拦截:裸
requests请求未携带合法浏览器标识,Upwork会直接返回安全验证页或空骨架页面,返回的HTML内容和浏览器中看到的职位搜索页完全不同,自然无法匹配目标节点。 - 动态渲染逻辑:Upwork职位列表为前端JavaScript异步拉取数据后动态插入DOM的内容,首次请求返回的静态HTML中不包含职位信息节点,静态解析初始HTML必然拿不到结果。
- 类名依赖脆弱:硬编码的多类名组合
my-0 p-sm-right job-tile-title中,部分类名是前端构建生成的可变类名,随站点版本迭代可能随时变更,匹配逻辑鲁棒性极差。
可落地方案
方案1:携带合法请求头调用后端接口(轻量高效,推荐)
直接请求职位搜索的后端接口拿结构化JSON数据,不需要解析HTML,稳定性更高。
import requests # 替换为你本地浏览器的实际请求头,模拟真实访问绕过基础反爬 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36", "Accept": "application/json, text/plain, */*", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "Referer": "https://www.upwork.com/nx/jobs/search/?q=web%20scraping&sort=recency", # 若请求返回403,可补全你登录Upwork后的Cookie字段,登录态下请求通过率更高 } search_params = { "q": "web scraping", "sort": "recency", "page": 1, "per_page": 20 } # 接口路径可通过浏览器F12网络面板筛选XHR请求获取,随站点版本更新可能调整 resp = requests.get("https://www.upwork.com/api/v3/jobs/search", headers=headers, params=search_params) resp.raise_for_status() job_result = resp.json() # 直接从结构化数据提取标题,无需依赖DOM类名 for job in job_result["results"]["jobs"]: print(job["title"])
- 抓取时建议设置3-5秒的请求间隔,避免高频请求触发IP封禁。
方案2:浏览器自动化渲染抓取(适配动态页面,逻辑简单)
如果接口参数加密难以调试,可以用自动化浏览器工具加载页面,等JS完成动态渲染后再解析DOM,和手动浏览页面的加载逻辑完全一致。
from bs4 import BeautifulSoup from playwright.sync_api import sync_playwright with sync_playwright() as p: # headless设为False可打开浏览器窗口查看实际加载过程 browser = p.chromium.launch(headless=True) page = browser.new_page(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36") page.goto("https://www.upwork.com/nx/jobs/search/?q=web%20scraping&sort=recency") # 等待职位标题节点加载完成,确保动态内容渲染完毕 page.wait_for_selector("h4.job-tile-title", timeout=10000) page_source = page.content() browser.close() soup = BeautifulSoup(page_source, "lxml") # 匹配类名时只保留稳定的业务类名job-tile-title,去掉可变的样式类名 title_list = soup.find_all("h4", class_="job-tile-title") for title in title_list: print(title.get_text(strip=True))
内容的提问来源于stack exchange,提问作者Wisam
相关产品推荐
相关产品推荐

