AttributeError报错排查及BS4查找div标签方法咨询
报错修复与BeautifulSoup4查找机制详解
一、报错原因
你遇到的AttributeError: 'NoneType' object has no attribute 'find',本质是listing = beautify.find('li', class_='iFjolb gws-plugins-horizon-jobs__li-ed')返回了None——也就是BeautifulSoup在页面里找不到符合条件的<li>标签。之后调用listing.find()时,自然会报错,因为None没有find方法。
二、BS4查找标签的核心机制
1. find() 方法
在当前节点(包括自身)的所有子节点中,查找第一个匹配条件的元素:
- 条件可以是标签名(如
'li')、class(用class_参数,因为class是Python关键字)、id等 - 找不到匹配元素时,返回
None
2. find_all() 方法
查找所有匹配条件的元素,返回一个列表:
- 找不到匹配元素时,返回空列表
[] - 适合批量抓取列表类数据(比如职位列表)
3. class匹配规则
当元素有多个class时,你可以:
- 用空格分隔的字符串(如
class_='iFjolb gws-plugins-horizon-jobs__li-ed'),匹配同时拥有这两个class的元素 - 用列表(如
class_=['iFjolb', 'gws-plugins-horizon-jobs__li-ed']),效果和上面一致,可读性更好
三、爬虫代码修复方案
Google Jobs页面有反爬机制,直接用requests.get()会被识别为机器人,返回的页面里没有你要的职位标签。加上以下修改即可解决:
1. 模拟浏览器请求
给requests.get()添加请求头,伪装成真实浏览器访问:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36' }
2. 处理空值,避免报错
在调用find()前,先判断父节点是否存在;用find_all()批量抓取所有职位项:
修改后的完整代码:
from bs4 import BeautifulSoup import requests # 模拟浏览器请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36' } url = 'https://www.google.com/search?q=Software+engineer+&sxsrf=ALiCzsaeLLjcCHZk46ernxCkoay7ldkDsA:1666897166012&source=hp&ei=DdVaY-CHOvvgkPIPxc2m6Ag&iflsig=AJiK0e8AAAAAY1rjHgG0CdqkcKPC3aVnmBvSGuZgc6Py&uact=5&oq=Job+listings&gs_lcp=Cgdnd3Mtd2l6EAMyBwgjEMkDECcyCggAEIAEEIcCEBQyDQgAEIAEELEDEIMBEAoyDQgAEIAEELEDEIMBEAoyBQgAEIAEMgUIABCABDIFCAAQgAQyCggAEIAEELEDEAoyDQgAEIAEELEDEIMBEAoyDQgAEIAEELEDEIMBEAo6BAgjECc6BQgAEJECOgsILhCABBCxAxCDAToLCAAQgAQQsQMQgwE6CwguEIAEEMcBENEDOg4ILhCABBCxAxCDARDUAjoLCC4QgAQQsQMQ1AI6EQguEIAEELEDEIMBEMcBEK8BOggIABCABBCxAzoHCAAQgAQQCjoICAAQyQMQkQI6EAgAEIAEEIcCELEDEIMBEBQ6DQgAEIAEEIcCELEDEBQ6CwguELEDEMcBENEDOhMILhCABBCHAhCxAxDHARDRAxAUOgsILhCABBDHARCvAToICC4QgAQQ5QRQAFjbFGDEFWgCcAB4AYABoQGIAcYLkgEEMy4xMJgBAKABAQ&sclient=gws-wiz&ibp=htl;jobs&sa=X&ved=2ahUKEwijh7Dti4H7AhXzkWoFHddJCAMQudcGKAJ6BAgNEC8#fpstate=tldetail&htivrt=jobs&htidocid=4XlU2-oL0UgAAAAAAAAAAA%3D%3D' # 发送带请求头的请求 response = requests.get(url, headers=headers) beautify = BeautifulSoup(response.text, 'lxml') # 抓取所有职位列表项 job_listings = beautify.find_all('li', class_=['iFjolb', 'gws-plugins-horizon-jobs__li-ed']) # 遍历处理每个职位 for listing in job_listings: # 安全获取公司名称 company_tag = listing.find('div', class_='oNwCmf') company_name = company_tag.text.strip() if company_tag else '未知公司' # 可以继续抓取其他信息,比如职位名称、地点 job_title_tag = listing.find('h3', class_='BjJfJf PUpOsf') job_title = job_title_tag.text.strip() if job_title_tag else '未知职位' print(f"职位:{job_title},公司:{company_name}")
四、导入数据库的建议
- 整理数据:把每个职位的信息(公司、职位名、地点、链接等)整理成字典,比如
job_data = {'title': job_title, 'company': company_name, ...} - 连接数据库:根据你用的数据库选择对应库,比如用SQLite可以用
sqlite3,MySQL用pymysql - 插入数据:编写SQL插入语句,把整理好的字典数据插入数据库,批量插入可提高效率
内容的提问来源于stack exchange,提问作者Mikehouse627
相关产品推荐
相关产品推荐

