使用Selenium+BeautifulSoup爬取网页生成字典遇报错及循环异常求解
问题原因与修正方案
问题1:仅获取最后一页数据
- 你的页面遍历循环和数据处理逻辑缩进错误,数据处理代码被放到了页面循环的外层,只会执行一次,调用的是最后一次页面加载完成后拿到的DOM元素,所以只能拿到最后一页的数据。
问题2:AttributeError报错
soup.find()返回的是单个<div>节点,直接遍历单个节点会把内部的纯文本节点(NavigableString类型)也遍历出来,这类节点没有text属性,所以调用text属性会触发报错。另外你没有提前给字典的键初始化空列表,直接调用append方法也会触发键不存在的报错。
修正后代码
from bs4 import BeautifulSoup import pandas as pd from selenium import webdriver DRIVER_PATH = '/usr/local/bin/chromedriver' driver = webdriver.Chrome(executable_path=DRIVER_PATH) # 提前初始化结果字典,给目标字段创建空列表 result = {'Current market value:': []} for i in range(1, 10): url = 'https://www.transfermarkt.co.uk/cristiano-ronaldo/profil/spieler/'+str(i) driver.get(url) # 隐式等待确保页面加载完成,可根据网络情况调整数值 driver.implicitly_wait(3) html = driver.page_source soup = BeautifulSoup(html, 'html.parser') # 用find_all获取所有对应class的div节点,自动过滤纯文本节点 market_left = soup.find_all('div', {'class':'right-td'}) market_right = soup.find_all('div', {'class':'left-td'}) # 配对左右节点内容 for left, right in zip(market_left, market_right): left_text = left.text.strip() right_text = right.text.strip() # 仅收集目标字段,不需要过滤可以删掉该判断 if left_text == 'Current market value:': result[left_text].append(right_text) print(result) # 用完关闭浏览器驱动 driver.quit()
补充说明
- 如果需要收集所有左右class配对的字段,删掉if判断,提前给
result字典中对应字段初始化空列表即可 - 网络较差的场景可以适当调大隐式等待的时间,或者改用显式等待定位目标元素,避免页面没加载完成就开始解析导致数据缺失
内容的提问来源于stack exchange,提问作者Stackcans
相关产品推荐
相关产品推荐

