如何从Scrapy Selector中删除子元素并排除blockquote引用内容?
报错原因
你触发类型错误的核心原因是w3lib.html下的处理方法仅接收字符串类型的HTML内容,你传入的post.css('div.bbWrapper')[0]是Scrapy的Selector对象,没有转换为原始HTML文本。
解决方案
方案1:使用w3lib修正写法(最小改动适配原有代码)
直接通过.get()方法获取选中节点的HTML字符串即可:
from w3lib.html import remove_tags, remove_tags_with_content # 获取div.bbWrapper的完整HTML文本 body_html = post.css('div.bbWrapper').get() # 先移除所有blockquote标签及内部内容,再清除剩余HTML标签保留纯文本 content = remove_tags(remove_tags_with_content(body_html, ('blockquote', )))
该方案自动兼容blockquote在任意位置的布局,不管引用在内容前、中、后都会被完整移除。
方案2:XPath直接提取(性能最优的原生Scrapy实现)
不需要引入额外处理库,直接通过XPath语法筛选所有不在blockquote内的文本节点,一步拿到结果:
# 筛选div.bbWrapper下所有祖先节点不包含blockquote的文本节点,拼接为完整内容 content = ''.join(post.xpath('//div[@class="bbWrapper"]//text()[not(ancestor::blockquote)]').getall())
方案3:Scrapy中混用Beautiful Soup
你完全可以在Scrapy的parse方法里任意调用Beautiful Soup,没有框架限制,写法如下:
from bs4 import BeautifulSoup body_html = post.css('div.bbWrapper').get() soup = BeautifulSoup(body_html, 'lxml') # 删除所有blockquote节点 for quote in soup.find_all('blockquote'): quote.decompose() # 提取纯文本内容 content = soup.get_text()
内容的提问来源于stack exchange,提问作者larapsodia
相关产品推荐
相关产品推荐

