Python 2.7用BeautifulSoup提取div报错:'NoneType'无get_text属性
解决BeautifulSoup提取div时出现的AttributeError问题
这个报错我太熟了!本质就是你用find方法查找目标div时根本没找到对应的元素,返回了None,之后你直接调用get_text()方法,自然就触发了AttributeError: 'NoneType' object has no attribute 'get_text'。下面咱们一步步排查解决:
为什么找不到目标div?
主要有这几个常见原因:
- 网站反爬拦截:直接用
urllib2请求时,服务器识别出你是爬虫,返回的内容和浏览器看到的不一样(甚至是空白或反爬页面),自然没有目标div。 - 页面内容动态加载:目标div是通过JavaScript渲染生成的,
urllib2只能获取静态HTML源码,拿不到JS动态生成的内容。 - 选择器写错了:可能class名拼写错误,或者页面结构已经更新,目标div的class/id变了。
一步步解决
第一步:先确认请求到的HTML内容里有没有目标div
先把请求到的源码打印出来,看看是不是和浏览器里的一致:
import urllib2 # 先加个浏览器UA,避免被直接拦截 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } req = urllib2.Request("https://www.metal-archives.com/lists/AF", headers=headers) openUrl = urllib2.urlopen(req) html_content = openUrl.read() # 打印源码,搜索有没有"dataTables_info"这个class print(html_content)
如果打印的内容里搜不到dataTables_info,那基本就是反爬或者动态加载的问题了。
第二步:解决反爬问题(模拟浏览器请求)
很多网站会检查请求的User-Agent字段,只要加上浏览器的UA就能绕过基础反爬,修改后的代码如下:
import urllib2 from bs4 import BeautifulSoup headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } req = urllib2.Request("https://www.metal-archives.com/lists/AF", headers=headers) openUrl = urllib2.urlopen(req) findCount = BeautifulSoup(openUrl, "html.parser") # 可以试试用CSS选择器,更直观 divStuff = findCount.select_one("div.dataTables_info") # 先判断是否找到元素,再调用方法 if divStuff: print(divStuff.get_text(strip=True)) else: print("未找到目标div元素,请检查选择器或页面结构")
第三步:如果是动态加载内容,用工具执行JS
如果加了UA还是找不到,那大概率是内容由JS动态渲染的,这时候urllib2就无能为力了,得用能执行JavaScript的工具,比如selenium:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from bs4 import BeautifulSoup # 配置无头模式,不用打开浏览器窗口 chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') # 这里需要你先安装ChromeDriver,并配置好路径 driver = webdriver.Chrome(options=chrome_options) driver.get("https://www.metal-archives.com/lists/AF") # 获取渲染后的页面源码 html_content = driver.page_source findCount = BeautifulSoup(html_content, "html.parser") divStuff = findCount.select_one("div.dataTables_info") if divStuff: print(divStuff.get_text(strip=True)) else: print("未找到目标div元素") # 记得关闭浏览器 driver.quit()
额外小技巧
- 以后调用
get_text()或text之前,一定要先判断元素是否为None,避免报错。 - 如果目标div有多个class,用
class_参数或者CSS选择器会更可靠,比如find("div", class_="dataTables_info")或者select_one("div.dataTables_info")。
内容的提问来源于stack exchange,提问作者Asking
相关产品推荐
相关产品推荐

