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

Python爬虫解决data-search-sol-meta属性token提取为None问题

问题根因
  • 取值逻辑错误:目标token、jobId等数据存储在div标签的data-search-sol-meta自定义属性中,并非标签包裹的内部文本。原代码使用.text.strip()取值,该div无可见内部文本,因此返回空值。
  • 流程逻辑错误:分页爬取时transform(c)写在for循环外部,仅会处理最后一页的返回内容;time.sleep(4)位置错误,无法在请求间生效防封禁效果。
  • 反爬缺失:requests默认请求头特征明显,访问JobStreet时会被反爬策略拦截,返回不含职位数据的异常页面。
  • 未做结构化转换:data-search-sol-meta的属性值为JSON格式字符串,直接读取文本无法拆分出独立的token、jobId字段。
修正后可运行代码
import time
import json
import requests
import pandas as pd
from bs4 import BeautifulSoup

# 浏览器请求头,伪装普通用户访问避免被反爬拦截
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',
    'Accept-Language': 'en-MY,en;q=0.9'
}
joblist = []

def extract(page):
    url = f'https://www.jobstreet.com.my/en/job-search/administrative-assistant-jobs/{page}/'
    r = requests.get(url, headers=HEADERS)
    # 校验请求状态,遇到403/404等异常直接抛出,避免解析空页面
    r.raise_for_status()
    soup = BeautifulSoup(r.content, 'html.parser')
    return soup


def transform(soup):
    # 直接匹配带data-search-sol-meta属性的标签,无需硬编码动态生成的CSS类名,避免前端类名变更导致匹配失效
    meta_tags = soup.find_all('div', attrs={'data-search-sol-meta': True})
    for tag in meta_tags:
        # 核心修正:读取标签自定义属性值,而非读取标签内部文本
        meta_str = tag.get('data-search-sol-meta')
        if not meta_str:
            continue
        # 解析JSON格式的元数据,拆分出需要的字段
        meta_data = json.loads(meta_str)
        job_detail = {
            'searchRequestToken': meta_data.get('searchRequestToken'),
            'token': meta_data.get('token'),
            'jobId': meta_data.get('jobId'),
            'section': meta_data.get('section'),
            'sectionRank': meta_data.get('sectionRank'),
            'jobAdType': meta_data.get('jobAdType')
        }
        joblist.append(job_detail)


if __name__ == '__main__':
    total_pages = 2
    for page in range(1, total_pages + 1):
        print(f'Crawling Progress: [{page}/{total_pages}]')
        page_soup = extract(page)
        transform(page_soup)
        # 请求间隔放在每次请求完成后,控制访问频率避免被封禁
        time.sleep(4)

    df = pd.DataFrame(joblist)
    # 测试打印结果前5行
    print(df.head())
关键改动说明
  • 取值逻辑修正:使用标签对象的.get('属性名')方法读取自定义属性值,替换原代码读取内部文本的错误逻辑。
  • 选择器优化:放弃硬编码编译生成的动态CSS类名,直接通过目标属性定位标签,适配站点前端迭代导致的类名变动。
  • 流程逻辑修正:将页面解析、请求延迟逻辑移入分页循环内,保证每一页的职位数据都能被正常抓取处理。
  • 反爬适配:添加真实浏览器请求头,增加请求状态校验,降低被反爬拦截的概率。
  • 数据结构化:通过json.loads()将属性值的JSON字符串解析为字典,直接提取目标字段,生成的DataFrame可直接用于后续分析,无需二次清洗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:36:20