使用Selenium与BeautifulSoup爬取网页段落生成Pandas DataFrame时的问题求助
你的爬虫问题拆解与解决方案
咱们一步步来解决你遇到的三个核心问题,帮你把爬虫跑通、跑快:
1. 频繁触发「InvalidSchema」异常
这个问题主要有两个原因:
- 无效链接过滤不全:你用Selenium抓取的所有
<a>标签里,很多href并不是HTTP/HTTPS链接(比如mailto:、javascript:、相对路径/page.html),requests.get()无法处理这类非HTTP协议的链接,直接抛出异常。 - 代码拼写错误:你写的
link.appned(str(e.get_attribute('href')))里,append拼成了appned——这个小错误会导致你根本存不下数据,就算没异常也拿不到结果。
解决办法:
- 先过滤有效链接:检查每个href是否以
http开头,或者把相对路径拼接成完整URL(比如/page.html拼上网站域名变成https://xxx.com/page.html)。 - 修复拼写错误:把
appned改成append。 - 精准捕获异常:别用裸
except,改成捕获requests.exceptions.InvalidSchema,这样能区分是链接无效还是其他错误。
2. 爬取速度太慢
你的当前写法是串行请求每个链接,而且还混合了Selenium(启动浏览器本身就很重)和requests,速度自然快不起来。
优化方向:
- 减少Selenium的使用:如果初始页面是静态的,直接用
requests+BeautifulSoup解析所有<a>标签,不用启动浏览器,能省不少时间。 - 用并发请求:用
requests.Session保持会话复用连接,或者用aiohttp做异步请求,把串行请求改成并行,速度能提升好几倍。 - 控制请求频率:别一下子请求太猛,加个小延迟(比如
time.sleep(0.5)),避免被网站反爬封禁。
3. 爬取Cognizant/SAS/BMC等网站无数据
这类大型企业网站反爬机制很完善,而且很多内容是动态加载的,你的写法踩了几个坑:
- 请求头被识别:
requests默认的User-Agent是python-requests/xxx,很容易被网站的反爬系统拦截,返回的是空白页面或者假页面,自然找不到<p>标签。 - 搜索字符串拼写错误:你写的
<seacrh_strng>里,search拼成了seacrh——就算页面有内容,也匹配不到你要的关键词。 - 动态内容未加载:这些网站很多内容是JS渲染的,
requests只能拿到静态HTML,看不到JS生成的<p>标签。
解决办法:
- 修复关键词拼写:把
<seacrh_strng>改成你实际要找的正确关键词(注意别带尖括号,除非你确实要匹配标签里的内容)。 - 添加浏览器请求头:给
requests.get()加上模拟浏览器的User-Agent,比如:headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'} response = requests.get(url, headers=headers) - 用Selenium处理动态页面:如果
requests拿不到内容,就用Selenium打开每个链接,等待页面加载完成后再解析(最好用WebDriverWait等待元素加载,别用time.sleep()硬等)。 - 检查页面结构:用浏览器开发者工具(F12)查看这些网站的
<p>标签是否真的存在,或者是否嵌套在<iframe>里,调整find_all的参数。
优化后的代码示例
import requests from bs4 import BeautifulSoup import pandas as pd from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time from requests.exceptions import InvalidSchema, RequestException # 配置参数 BASE_DOMAIN = "https://www.cognizant.com" TARGET_KEYWORD = "digital transformation" # 替换成你要找的正确关键词 HEADERS = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } # 初始化Selenium(用于处理动态内容) driver = webdriver.Chrome(executable_path='D:\WebScrapp\chromedriver.exe') wait = WebDriverWait(driver, 10) driver.get(BASE_DOMAIN) # 获取并清洗所有有效链接 raw_links = [] try: # 等待页面加载完成,获取所有a标签 link_elements = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//a[@href]"))) for elem in link_elements: href = elem.get_attribute('href') if not href: continue # 处理相对路径,拼接成完整URL if href.startswith('/'): full_link = BASE_DOMAIN + href elif href.startswith('http'): full_link = href else: # 跳过mailto、javascript等无效链接 continue raw_links.append(full_link) except Exception as e: print(f"获取链接时出错: {str(e)}") # 去重,避免重复爬取 unique_links = list(set(raw_links)) print(f"共获取到 {len(unique_links)} 个有效链接") # 存储结果的列表 link_list = [] para_list = [] for link in unique_links: try: # 优先用requests获取静态内容,速度更快 response = requests.get(link, headers=HEADERS, timeout=10) response.raise_for_status() # 抛出HTTP错误(比如404、500) soup = BeautifulSoup(response.content, 'lxml') paras = soup.find_all('p') except (InvalidSchema, RequestException): # 如果requests失败,用Selenium加载动态页面 print(f"Requests无法加载 {link},切换到Selenium") try: driver.get(link) # 等待页面核心内容加载 wait.until(EC.presence_of_element_located((By.TAG_NAME, 'p'))) soup = BeautifulSoup(driver.page_source, 'lxml') paras = soup.find_all('p') except Exception as e: print(f"Selenium加载 {link} 失败: {str(e)}") continue except Exception as e: print(f"处理 {link} 时出错: {str(e)}") continue # 筛选包含目标关键词的段落 for p in paras: p_text = p.text.strip() if TARGET_KEYWORD in p_text: link_list.append(link) para_list.append(p_text) # 生成DataFrame df = pd.DataFrame({'Link': link_list, 'Para': para_list}) print("\n爬取结果:") print(df) # 关闭浏览器 driver.quit()
内容的提问来源于stack exchange,提问作者pythondumb
相关产品推荐
相关产品推荐

