Scrapy爬取SignalStart表格时td文本提取问题及后续处理问询
解决Scrapy爬取SignalStart表格时提取TD文本的问题
嘿,我帮你梳理下这个爬取表格的问题,以及怎么从TD选择器里正确提取文本~
问题根源:初始代码拿不到Name的原因
你最开始的代码里,provider.xpath('td[2]/text()').get()拿不到内容,大概率是因为第二个TD里的文本不是直接在TD标签下,而是嵌套在子标签里(比如<a>链接标签)。/text()只会取当前标签的直接文本节点,子标签里的文本它是看不到的,所以返回空。
正确提取TD文本的方法
你更新后的代码已经能遍历到每个TD的Selector对象(也就是datum),现在要做的就是从这个Selector里提取所有后代文本,这里有两种实用的方式:
方法1:手动拼接文本并清理空格
对于每个datum,用.//text()获取该节点下所有的文本内容(包括子标签里的),再把列表拼接成干净的字符串:
text_content = ' '.join(datum.xpath('.//text()').getall()).strip()
.//text():点开头表示相对当前节点的所有后代文本节点,避免爬到页面其他无关文本getall():返回所有匹配到的文本列表' '.join():把列表文本拼接成字符串,同时自动合并多个换行/空格为单个空格strip():去除字符串首尾的空白字符
方法2:用XPath内置函数一键清理(更简洁)
XPath的normalize-space()函数可以自动完成文本拼接和空格清理,直接返回规整后的内容:
text_content = datum.xpath('normalize-space(.)').get()
这个函数会把节点内所有文本拼接,同时去除首尾空格,把中间的各类空白(换行、制表符、多空格)替换成单个空格,非常省心!
修改后的完整代码
把你的代码里data_row[td[i]] = datum替换成上述任意一种方法即可,这里用第二种更简洁的方式:
import scrapy from behold import Behold class SignalStartSpider(scrapy.Spider): name = 'signalstart' start_urls = [ 'https://www.signalstart.com/search-signals', ] def parse(self, response): cols = "rank name gain pips drawdown trades type monthly chart price age added action" skip = [9,13] # 构建索引到列名的映射 td_index_to_col = {i: col for i, col in enumerate(cols.split())} Behold().show('td_index_to_col') for provider in response.xpath("//div[@class='row']//tr"): data_row = dict() for i, datum in enumerate(provider.xpath('td')): if i in skip: continue # 提取清理后的文本内容 data_row[td_index_to_col[i]] = datum.xpath('normalize-space(.)').get() # Behold().show('datum') yield data_row
额外小技巧
- 可以用Scrapy Shell快速调试:运行
scrapy shell https://www.signalstart.com/search-signals,然后用response.xpath("//div[@class='row']//tr[1]/td[2]").xpath('normalize-space(.)').get()测试能不能拿到Name,调试效率更高 - 如果某些TD里包含图片或其他非文本元素,
normalize-space(.)会自动忽略标签,只提取有效文本
内容的提问来源于stack exchange,提问作者Terrence Brannon
相关产品推荐
相关产品推荐

